我有四个参数:t1、t2、theta1 和 theta2。我想找到以下方程组的解(可能有无限多个):
t1*cos(theta1) + t2*cos(theta2) + 2*t1*t2*sin(theta1 + theta2) = t1*sin(theta1) + t2*sin(theta2) + 2*t1*t2*cos(theta1 + theta2) + 1
t1*cos(theta1) + t2*cos(theta2) + t1*sin(theta1) + t2*sin(theta2) = 2*t1*t2*sin(theta1 + theta2) + 2*t1*t2*cos(theta1 + theta2) + 1
2*t1^2*t2^2 + sin(theta1)*t1*t2^2 + sin(theta1 + theta2)*t1*t2 + 1 = sin(theta2)*t1^2*t2 + t1^2 + sin(theta1)*t1 + t2^2
由于参数多于方程,我们必须施加进一步的限制来确定该系统的特定解。现在我并不关心选择哪个解决方案,只要它不是微不足道的(就像所有变量都等于零)。
我目前的方法是将第三个方程设置为0.5,用theta1和theta2求解t1和t2,并将这些表达式代入前两个方程来求解theta1和theta2。然而,MATLAB 试图以符号方式完成此操作,这是极其耗时的。有什么办法可以得到这个系统的一些近似解吗?我无法精确地绘制这些方程所表示的曲面并查看它们的交集,因为方程的每一边都涉及两个以上的参数,这意味着它无法在三个维度上可视化。
最佳答案
您可以使用fsolve
来做到这一点。
首先,您需要为三个方程的残差创建匿名函数。我要创建一个向量 x
哪里x = [t1; t2; theta1; theta2]
。这使得残差:
r1 = @(x) x(1)*cos(x(3)) + x(2)*cos(x(4)) + 2*x(1)*x(2)*sin(x(3) + x(4)) - (x(1)*sin(x(3)) + x(2)*sin(x(4)) + 2*x(1)*x(2)*cos(x(3) + x(4)) + 1);
r2 = @(x) x(1)*cos(x(3)) + x(2)*cos(x(4)) + x(1)*sin(x(3)) + x(2)*sin(x(4)) - (2*x(1)*x(2)*sin(x(3) + x(4)) + 2*x(1)*x(2)*cos(x(3) + x(4)) + 1);
r3 = @(x) 2*x(1)^2*x(2)^2 + sin(x(3))*x(1)*x(2)^2 + sin(x(3) + x(4))*x(1)*x(2) + 1 - (sin(x(4))*x(1)^2*x(2) + x(1)^2 + sin(x(3))*x(1) + x(2)^2);
然后,我们需要创建一个函数,它是这三个残差的向量,因为 fsolve
尝试使该向量为零:
r = @(x) [r1(x); r2(x); r3(x)]
现在,我们调用fsolve
。我选择了一个任意的起点:
>> [x, fval, exitflag] = fsolve(r, [0.5,0.5,pi/4,pi/4])
Warning: Trust-region-dogleg algorithm of FSOLVE cannot handle non-square systems; using Levenberg-Marquardt algorithm instead.
> In fsolve at 287
Equation solved.
fsolve completed because the vector of function values is near zero
as measured by the default value of the function tolerance, and
the problem appears regular as measured by the gradient.
<stopping criteria details>
x =
0.9654 0.5182 0.7363 0.7344
fval =
1.0e-10 *
-0.0090
0.2743
-0.0181
exitflag =
1
您可以忽略该警告。 x
是您正在寻找的四个值。 fval
是残差值。 exitFlag == 1
意味着我们找到了根。
关于matlab - 如何让 MATLAB 对一个特别棘手的方程组进行数值求解?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31300907/