Ask Your Question
2

How to recursively substitute from global name space?

asked 2012-11-14 09:56:27 +0100

stan gravatar image

In sage 3.x, I used the below function to automatically substitute into an expression all assignments I have made previously. How can I get it to work in Sage 5.x or is there a better way now?

def subsg(variable, *args):
    """
    Substitutes all definitions in the global name space for the variables contained in 'variable' and returns the result.
    INPUT:
        variable -- a symbolic variable
        *args -- an optional dictionary containing additional parameter definitions
    EXAMPLE:
        sage: var ('a b c d')
        a b c
        sage: f = a*x
        sage: a = 2*b
        sage: b = c^2
        sage: cons1 = dict(c = d^3)
        sage: subsg(f,cons1)
        2*d^6*x
    Or, if cons1 is not to be used:
        sage: subsg(f)
        2*c^2*x

    """
    expr1 = variable
    expr2 = variable.subs(globals()).subs(*args)
    while expr1 <> expr2:
        expr1 = expr2
        expr2 = expr1.subs(globals()).subs(*args)
    return expr1
edit retag flag offensive close merge delete

Comments

I've been trying to find the same thing -- so far all I could find was this question, and the same question you asked on google groups in 2008.

adamhg gravatar imageadamhg ( 2013-02-21 00:25:34 +0100 )edit

1 Answer

Sort by ยป oldest newest most voted
1

answered 2013-05-16 14:41:55 +0100

David Bailey gravatar image

updated 2013-06-01 10:25:20 +0100

Here is a new version of your "subsg" function, with modifications partly inspired by the "update" function from a related question. This seems to work in Sage 5.9 for your examples and in other cases that I have tried so far:

def subsg(expression, *args):
"""
Substitutes all definitions in the global name space for the variables contained in 'expression' and returns the result.
INPUT:
    expression -- a symbolic expression
    *args -- an optional dictionary containing additional parameter definitions
EXAMPLE:
    sage: var ('a b c d')
    a b c
    sage: f = a*x
    sage: a = 2*b
    sage: b = c^2
    sage: cons1 = dict(c = d^3)
    sage: subsg(f,cons1)
    2*d^6*x
Or, if cons1 is not to be used:
    sage: subsg(f)
    2*c^2*x

"""
variables = globals().update(*args)
expr1 = expression
try :
    expr2 = expr1.subs(dict(zip(expr1.variables(), map(lambda v:eval(str(v)), expr1.variables()))))
except:
    # Return original expression unchanged if there is an error
    return expr1
while expr1 <> expr2:
    expr1 = expr2
    expr2 = expr1.subs(dict(zip(expr1.variables(), map(lambda v:eval(str(v)), expr1.variables()))))
return expr1
edit flag offensive delete link more

Comments

Brilliant, thank you!

stan gravatar imagestan ( 2013-05-17 04:08:06 +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

1 follower

Stats

Asked: 2012-11-14 09:56:27 +0100

Seen: 449 times

Last updated: Jun 01 '13