Ask Your Question
3

How to dynamically substitute a variable in a callable function?

asked 2012-03-24 21:51:48 +0100

JoalHeagney gravatar image

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 flag offensive close merge delete

Comments

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.

kcrisman gravatar imagekcrisman ( 2012-03-26 23:25:42 +0100 )edit

1 Answer

Sort by ยป oldest newest most voted
3

answered 2012-03-24 23:23:29 +0100

DSM gravatar image

updated 2012-03-24 23:30:30 +0100

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)
edit flag offensive delete link more

Comments

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

kcrisman gravatar imagekcrisman ( 2012-03-26 23:24:14 +0100 )edit

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

JoalHeagney gravatar imageJoalHeagney ( 2012-04-09 23:26:04 +0100 )edit

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?

Szilard SZALAY gravatar imageSzilard SZALAY ( 2013-09-17 08:09:08 +0100 )edit

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

3 followers

Stats

Asked: 2012-03-24 21:51:48 +0100

Seen: 2,606 times

Last updated: Mar 24 '12