我有两个单变量函数f(x)
和g(x)
,我想用g(x) = y
替换f(x)
作为某些f2(y)
。
这是一个有效的简单示例:
In [240]: x = Symbol('x')
In [241]: y = Symbol('y')
In [242]: f = abs(x)**2 + 6*abs(x) + 5
In [243]: g = abs(x)
In [244]: f.subs({g: y})
Out[244]: y**2 + 6*y + 5
但是现在,如果我尝试一个稍微复杂的例子,那就失败了:
In [245]: h = abs(x) + 1
In [246]: f.subs({h: y})
Out[246]: Abs(x)**2 + 6*Abs(x) + 5
是否存在适用于此问题的一般方法?
答案 0 :(得分:4)
表达式abs(x)**2 + 6*abs(x) + 5
实际上并不包含abs(x) + 1
,因此无法替代。
可以想象将其更改为abs(x)**2 + 5*(abs(x) + 1) + abs(x)
,替换结果为abs(x)**2 + 5*y + abs(x)
。或者可能将其更改为abs(x)**2 + 6*(abs(x) + 1) - 1
,结果为abs(x)**2 + 6*y - 1
。还有其他选择。结果应该是什么?
此任务没有通用的方法,因为它不是一个明确定义的任务。
相反,替换f.subs(abs(x), y-1)
是一个明确的指令,用y-1
替换表达式树中所有出现的abs(x)。它返回6*y + (y - 1)**2 - 1
除了subs
之外,SymPy还有一个支持通配符的方法.replace
,但我不希望它在这里提供帮助。根据我的经验,它过于急于取代:
>>> a = Wild('a')
>>> b = Wild('b')
>>> f.replace(a*(abs(x) + 1) + b, a*y + b)
5*y/(Abs(x) + 1) + 6*y*Abs(x*y)/(Abs(x) + 1)**2 + (Abs(x*y)/(Abs(x) + 1))**(2*y/(Abs(x) + 1))
没有"消除"在SymPy。可以尝试通过引入另一个变量(例如,
)来使用solve
来模拟它
fn = Symbol('fn')
solve([Eq(fn, f), Eq(abs(x) + 1, y)], [fn, x])
试图解决" fn"和" x",因此" fn"的解决方案是没有x的表达式。 如果有效
事实上,它不适用于abs()
;在SymPy中没有实现解决绝对值内的东西。这是一种解决方法。
fn, ax = symbols('fn ax')
solve([Eq(fn, f.subs(abs(x), ax)), Eq(ax + 1, y)], [fn, ax])
这会输出[(y*(y + 4), y - 1)]
,其中第一个词是你想要的; fn
的解决方案。