我有一个函数 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 正试图证明 cat 复数值的所有可能组合的这种关系。简化也是一个定义不明确的过程——来自 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/

10-12 15:42