Opened 5 years ago

Last modified 2 years 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 3 years ago by rws

See also #22401.

comment:2 follow-up: Changed 2 years ago by schymans

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 2 years ago by egourgoulhon

Replying to schymans:

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.

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 2 years ago by schymans

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

Last edited 2 years ago by schymans (previous) (diff)
Note: See TracTickets for help on using tickets.