是的,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 上)。
当数值算法表现不佳时,可能表明将系统转换为精确的系统(这就是它的作用)会有所帮助。(实际上,将所有 0.5 替换为 1/2 将使错误消失。)
另一种选择是使用 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 错误,我们可以愉快地忽略它们。
输出的其余部分告诉我们,第一个解 (-0.5c,0.5c) 只有在 c=0 时才有效(ta 和 tb >= 0),这应该是显而易见的。当 tc<0 且 tc <= c <= -2 tc 时(或当 c=tc=0,这是包含这两种情况的简并解决方案)时,第二个解决方案有效。
最后,如果 ratnz 是一个问题,请从以下代码开始:
Off["ratnz"];
这应该会抑制错误,假设您对以下事实感到满意:有时 Mathematica 会采取这种策略来求解输入的方程,就好像它们是数字一样,但最好用符号来求解。