我正试图用mathematica求解方程组。这是我的代码。
f1[TA_, TB_] := TA - TB + C
f2[TA_, TB_] :=
TA*(TB - TA) + TA*TB + 0.5*TA^2 + TB*(TB - TA) + 0.5*TB^2
Solve[{f1[TA, TB] == 0, f2[TA, TB] == 0}, {TA, TB}]
Mathematica给我的输出很奇怪,我认为这是错误的(T变量代表时间,因此它们不能为负)。 You can see the output here.
0.-1.5C是什么意思?这是指-1.5C吗?
感谢您的帮助。
答案 0 :(得分:2)
是的,0。-1.5C表示-3C / 2,但是用“Real”而不是“Rational”语言编写。您的输入使用小数,Mathematica将其解释为近似/数值数据,而非精确的有理数。 “0”。表示Mathematica可以计算的浮点实数,几乎接近于零。但你可以检查:
Head[0.]
Head[0]
..你会发现0.是真实的但是0是一个整数。 0.5和1/2之间存在类似的区别。
我相信有几种方法可以改善这种情况,至少已经提到过其中一种方法。
首先,大写字母C是内置符号。通常,更好的是使用n,c,d等小写字母
其次,这些功能不需要延迟评估,因此:=是多余的。
但是,这并不是问题的真正原因。甚至纠正这些小问题:
f1[ta_, tb_] = ta - tb + c;
f2[ta_, tb_] = ta*tc + ta*tb + 0.5*ta^2 + tb*tc + 0.5*tb^2;
Solve[{f1[ta, tb] == 0, f2[ta, tb] == 0}, {ta, tb}]
...仍然会导致同样的错误。为什么?好吧,Mathematica以一种特殊的方式解决非线性方程,这样(当用“数值”数据表示时,即方程中有0.5而不是1/2),它试图用数字方法求解它们(与NSolve相同)。
然而,用数字方式求解方程式不同于象征性地这样做。正如我们在这里看到的那样,数值算法可能会对象征性地解决的系统产生问题。我不太了解NSolve知道为什么会产生这个错误,它将取决于NSolve使用的算法,但它可能与解决方案附近的这个系统的雅可比行列式可能为零的事实有关(取决于在tc)。
当数值算法行为笨拙时,可能表明将系统转换为精确的算法(这就是它的作用)将有所帮助。 (实际上,用1/2替换全部0.5会使错误消失。)
另一种选择是使用FindRoot,但仅限于此处没有其他符号如tc或c的情况。 (如果你修复了c = 1和tc = 2,或者任何其他值,FindRoot将无误地运行,而Solve或NSolve仍然会产生与仍然有效的解决方案相同的错误。)
对您而言可能有用/有用的一件事是:
f1[ta_, tb_] = ta - tb + c;
f2[ta_, tb_] = ta*tc + ta*tb + 0.5*ta^2 + tb*tc + 0.5*tb^2;
SOL = Solve[{f1[ta, tb] == 0, f2[ta, tb] == 0}, {ta, tb}]
Reduce[ReplaceAll[{ta >= 0, tb >= 0}, SOL[[1]]], {ta, tb}]
Reduce[ReplaceAll[{ta >= 0, tb >= 0}, SOL[[2]]], {ta, tb}]
另外两行采用这个等式的两个解,并检查ta和tb是否为非负数,因为这是你感兴趣的东西。为此,输出为:
{{ta -> 0. - 0.5 c, tb -> 0. + 0.5 c}, {ta -> -0.5 c - 1. tc, tb -> 0.5 c - 1. tc}}
c == 0
(tc < 0 && 2. tc <= c <= -2. tc) || (tc == 0 && c == 0)
一种解决方案是(-0.5c,0.5c),另一种是(-0.5c-tc,0.5c-tc)
输出还包括三个ratnz错误,我们可以高兴地忽略它。
输出的其余部分告诉我们,只有当c = 0时,第一个解(-0.5c,0.5c)才有效(ta和tb> = 0),这应该是显而易见的。当tc <0且tc <= c <= -2 tc时(或当c = tc = 0时,这是包括两种情况的简并解决方案),第二种解决方案是有效的。
最后,如果ratnz是个问题,请使用以下命令启动代码:
Off["ratnz"];
这应该可以抑制误差,假设您对以下事实感到满意:Mathematica有时会通过这种方法来解决输入的方程式,就好像它们是数字的,但是象征性地更好地解决了。