# How to dynamically substitute a variable in a callable function? Hi guys, this is a little problem I came across a week ago.

I'm trying to define a python function that accepts:
1. a callable sage function (of potentially more than one variable) as the first argument (henceforth called func), and
2. a symbolic variable as the second argument (henceforth called xsub)

My function then needs to define a dummy symbolic variable (t), and substitute xsub with t in func.
I can do this for one variable equations in current 4.8 sagemath, by ignoring the new substitution syntax, but it throws up a depreciation warning (Which I'm assuming will become an error in 5.0).

Here's what my code looks like:

def fracintegral(func,xsub,n,a=0):
var('t')
assume(x>a)
assume(t>a)
return integrate((x-t)^(n-1)*func(t),t,a,x)

The last line should look something like:

    return integrate((x-t)^(n-1)*func(x=t),t,a,x)
in order to avoid Depreciation Warnings, but this hardcodes x as the variable to be substituted. (Useless if my func is a y function.)

If I try:

    return integrate((x-t)^(n-1)*func(xsub=t),t,a,x)

then substitution of func(x=t) doesn't occur (and the integrate function effectively treats func as a constant with respect to dt).

Trying:

    return integrate((x-t)^(n-1)*func.subs(xsub==t),t,a,x)
doesn't work either, same result as func(xsub=t).

So, any idea how a function can accept a symbolic variable, and dynamically substitute out that variable in a callable function?

edit retag close merge delete

On an unrelated note, you may want to see if there is a way to do this without redeclaring t each time. Does that remove the assumptions on t? You can debug this with assumptions(). My first guess would be that it doesn't... but I could be wrong. Even after having spent a lot of time with our assumptions code, I still don't fully understand how it interacts with Maxima.

Sort by » oldest newest most voted Are you thinking of something like this?

def fracintegral(func,xsub,n,a=0):
t = var('t')
assume(x>a)
assume(t>a)
return integrate((x-t)^(n-1)*func.subs({xsub:t}),t,a,x)


which gives a deprecation-free

sage: var("x y")
(x, y)
sage: f1 = function("f", x)
sage: fracintegral(f1, x, 4)
-integrate((t - x)^3*f(t), t, 0, x)
sage: f2 = function("f", x, y)
sage: fracintegral(f2, y, 4)
-integrate((t - x)^3*f(x, t), t, 0, x)
sage: f3(x,y) = x^2+sin(y)
sage: fracintegral(f3, y, 4)
(x, y) |--> 1/4*x^6 + x^3 - 6*x + 6*sin(x)

more

Clever. So why doesn't func.subs(xsub=t) work, since that should be functionally equivalent?

Maybe something to do with hashing of the xsub key in the dictionary?

This solution is working for subs() but not for limit(). Could you give us please some explanation or link about what is really going in the background?