Opened 4 years ago

Last modified 20 months ago

## #17757 new defect

# substitute_function with var argument

Reported by: | rws | Owned by: | |
---|---|---|---|

Priority: | minor | Milestone: | sage-6.5 |

Component: | symbolics | Keywords: | |

Cc: | Merged in: | ||

Authors: | Reviewers: | ||

Report Upstream: | N/A | Work issues: | |

Branch: | Commit: | ||

Dependencies: | Stopgaps: |

### Description

sage: a,y,z=var('a,y,z') sage: (x*sin(sin(x + y + 2*a))).substitute_function(sin,cos) x*cos(cos(2*a + x + y)) sage: (x*sin(sin(x + y + 2*a))).substitute_function(sin,z) /home/ralf/sage/local/lib/python2.7/site-packages/sage/symbolic/expression_conversions.py:223: DeprecationWarning: Substitution using function-call syntax and unnamed arguments is deprecated and will be removed from a future release of Sage; you can use named arguments instead, like EXPR(x=..., y=...) See http://trac.sagemath.org/5930 for details. return self.composition(ex, operator) (2*a + x + y)*x

The method would be expected to give a meaningful error when seeing a variable as second argument.

### Change History (4)

### comment:1 Changed 2 years ago by

### comment:2 follow-up: ↓ 3 Changed 20 months ago by

Actually, the docstring of `.substitute_function()`

is grammatically incorrect and totally misleading:

Docstring: Return this symbolic expressions all occurrences of the function *original* replaced with the function *new*.

I assume that it is supposed to replace all occurrences of the function *original* with the function *new*, so it should return an error whenever one of the arguments is not a function. However, it is quite useful to substitute an expression for a function (see also https://ask.sagemath.org/question/26114/why-is-basic-arithmetic-disallowed-on-symbolic-functions/):

var('T', 'x') BT = function('B')(T) eq_T = BT == x*T eq_dT = diff(eq_T, T) print eq_dT f(T,x) = T^2 print eq_dT.substitute_function(B, f)

returns

diff(B(T), T) == x 2*T == x

Note, actually that T is a callable symbolic expression. In the below example, I do a less meaningful substitution, which again gives the right result if I substitute a callable symbolic expression, but if I substitute an expression, it gives the wrong result:

g(T,x) = x^2 print eq_dT.substitute_function(B, g) print eq_dT.substitute_function(B, x^2) print eq_dT.substitute_function(B, g(T,x))

This returns

0 == x 2*T == x 2*T == x

Only the first result is correct. In the other two, `x^2`

is treated as if it was `T^2`

. Surely, this is a bug.

### comment:3 in reply to: ↑ 2 Changed 20 months ago by

Replying to schymans:

This returns

0 == x 2*T == x 2*T == xOnly the first result is correct. In the other two,

`x^2`

is treated as if it was`T^2`

. Surely, this is a bug.

Note that the second and third results are accompanied by a deprecation warning:

/home/eric/sage/8.0.rc0/local/lib/python2.7/site-packages/sage/symbolic/expression_conversions.py:1969: DeprecationWarning: Substitution using function-call syntax and unnamed arguments is deprecated and will be removed from a future release of Sage; you can use named arguments instead, like EXPR(x=..., y=...) See http://trac.sagemath.org/5930 for details. return operator.change_function(self.new)(*[self(_) for _ in ex.operands()])

So, after the deprecation period is over, they will return an error, as it should.

### comment:4 Changed 20 months ago by

Thanks, I might have turned off warnings in the notebook. However, in the console,the deprecation warning is misleading, as it only asks for named arguments, which isn't even an option for `substitute_function`

:

┌────────────────────────────────────────────────────────────────────┐ │ SageMath version 7.6, Release Date: 2017-03-25 │ │ Type "notebook()" for the browser-based notebook interface. │ │ Type "help()" for help. │ └────────────────────────────────────────────────────────────────────┘ sage: var('T', 'x') (T, x) sage: BT = function('B')(T) sage: eq_T = BT == x*T sage: eq_dT = diff(eq_T, T) sage: f(T,x) = T^2 sage: print eq_dT.substitute_function(B, f) 2*T == x sage: g(T,x) = x^2 sage: print eq_dT.substitute_function(B, g) 0 == x sage: print eq_dT.substitute_function(B, x^2) /home/sschyman/Programs/sage-upgrade/local/lib/python2.7/site-packages/sage/symbolic/expression_conversions.py:1963: DeprecationWarning: Substitution using function-call syntax and unnamed arguments is deprecated and will be removed from a future release of Sage; you can use named arguments instead, like EXPR(x=..., y=...) See http://trac.sagemath.org/5930 for details. return operator.change_function(self.new)(*[self(_) for _ in ex.operands()]) 2*T == x

**Note:**See TracTickets for help on using tickets.

See also #22401.