Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

Modifying your "subsg" function, partly inspired by the "update" function from a related question, this new version that seems to work for your examples and in other cases 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
expr2 = expr1.subs(dict(zip(expr1.variables(), map(lambda v:eval(str(v)), expr1.variables()))))
while expr1 <> expr2:
    expr1 = expr2
    expr2 = expr1.subs(dict(zip(expr1.variables(), map(lambda v:eval(str(v)), expr1.variables()))))
return expr1

Modifying Here is a new version of your "subsg" function, with modifications partly inspired by the "update" function from a related question, this new version that . 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
expr2 = expr1.subs(dict(zip(expr1.variables(), map(lambda v:eval(str(v)), expr1.variables()))))
while expr1 <> expr2:
    expr1 = expr2
    expr2 = expr1.subs(dict(zip(expr1.variables(), map(lambda v:eval(str(v)), expr1.variables()))))
return expr1
click to hide/show revision 3
Added error handling to code in answer

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