我有一个函数 f
定义为:
syms c a t
f = symfun(c + t - (2*(t - 2^(1/2)*(a*t)^(1/2))*(a - t/2))/(2*a - t), [c a t])
但是,检查与简化版本的相等性会产生:
isequaln(f, simplify(f))
ans =
0
simplify
不会返回与原始函数完全等效的函数吗? 最佳答案
isequaln
的问题
sym/isequaln
可能不是用于测试相等性的合适函数。来自 sym/isequaln
的帮助:
正如@Benoit_11 所暗示的那样,文档并不完全清楚,但是,就像它是数字等价物一样,该函数似乎正在测试 equality, not identity(尽管不幸使用了“相同”一词)。简化函数是未简化函数的恒等式,但不是等价的。根据文档,sym/isequaln
可能会考虑 assumptions
和可能的简单关系之类的东西,但它不会在内部执行转换和简化。这几乎可以肯定是因为简化是一个计算成本很高的过程,因此很可能是一个设计决策,只包括一些定义明确(但没有详细记录)的测试。
有陷阱的可能解决方案
那么,你怎么能继续呢?除了 sym/isequaln
,Symbolic Math 工具箱还包括 isAlways
来更严格地测试等式和不等式:
syms c a t
f = symfun(c + t - (2*(t - 2^(1/2)*(a*t)^(1/2))*(a - t/2))/(2*a - t), [c a t])
g = simplify(f)
isAlways(f==g)
但是,在 R2014b 中,这会返回
false
和以下警告:Warning: Cannot prove 'c + t - ((2*t - 2*2^(1/2)*(a*t)^(1/2))*(a - t/2))/(2*a - t) == c +
2^(1/2)*(a*t)^(1/2)'.
> In /Applications/MATLAB_R2014b.app/toolbox/symbolic/symbolic/symengine.p>symengine at 56
In sym.isAlways at 38
您应该知道符号变量默认被假定为复数,并且
isAlways
正试图证明 c
、 a
和 t
复数值的所有可能组合的这种关系。简化也是一个定义不明确的过程——来自 simplify
的文档:如果您仔细查看原始方程,您会发现它包含一个已被简化的奇点。在 R2014b 中,计算
g(1,1,2)
返回 3
,但计算 f(1,1,2)
返回:Error using mupadmex
Error in MuPAD command: Division by zero. [_power]
Evaluating: _symans_32_15992
...
使用假设
如果您对符号变量有所了解,则可以通过应用假设来避免这种情况,例如
syms c a t
f = symfun(c + t - (2*(t - 2^(1/2)*(a*t)^(1/2))*(a - t/2))/(2*a - t), [c a t])
g = simplify(f)
assume(t>2*a)
isAlways(f==g)
现在返回
true
。顺便说一句,使用@Benoit_11 的例子,syms a b; isAlways((a+b)^2==a^2+2*a*b+b^2)
也直接返回 true
。关于matlab - 为什么 isequaln(f,simple(f)) 是假的?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/26737686/