假设我们有三个方程式:
eq1 = x1 + (x1 - x2) * t - X == 0;
eq2 = z1 + (z1 - z2) * t - Z == 0;
eq3 = ((X-x1)/a)^2 + ((Z-z1)/b)^2 - 1 == 0;
虽然有六个已知变量:
a = 42 ;
b = 12 ;
x1 = 316190;
z1 = 234070;
x2 = 316190;
z2 = 234070;
所以我们正在寻找三个未知变量:
X , Z and t
我写了两个方法来解决它。但是,由于我需要为570万个数据运行这些代码,因此它变得非常慢。
方法一(使用"解决"):
tic
S = solve( eq1 , eq2 , eq3 , X , Z , t ,...
'ReturnConditions', true, 'Real', true);
toc
X = double(S.X(1))
Z = double(S.Z(1))
t = double(S.t(1))
方法一的结果:
X = 316190;
Z = 234060;
t = -2.9280;
Elapsed time is 0.770429 seconds.
方法二(使用" fsolve"):
coeffs = [a,b,x1,x2,z1,z2]; % Known parameters
x0 = [ x2 ; z2 ; 1 ].'; % Initial values for iterations
f_d = @(x0) myfunc(x0,coeffs); % f_d considers x0 as variables
options = optimoptions('fsolve','Display','none');
tic
M = fsolve(f_d,x0,options);
toc
方法二的结果:
X = 316190; % X = M(1)
Z = 234060; % Z = M(2)
t = -2.9280; % t = M(3)
Elapsed time is 0.014 seconds.
虽然,第二种方法更快,但仍需要改进。如果您有更好的解决方案,请告诉我。谢谢
*额外信息: 如果你有兴趣知道这3个方程是什么,前两个是二维线的方程,第三个方程是一个椭圆方程。我需要找到线与椭圆的交点。显然,我们有两点结果。但是,为了简单起见,让我们忘记第二个答案。
答案 0 :(得分:1)
我的建议是使用第二个approce,这是matlab推荐的非线性方程组。 声明一个M函数
function Y=mysistem(X)
%X(1) = X
%X(2) = t
%X(3) = Z
a = 42 ;
b = 12 ;
x1 = 316190;
z1 = 234070;
x2 = 316190;
z2 = 234070;
Y(1,1) = x1 + (x1 - x2) * X(2) - X(1);
Y(2,1) = z1 + (z1 - z2) * X(2) - X(3);
Y(3,1) = ((X-x1)/a)^2 + ((Z-z1)/b)^2 - 1;
end
然后解决使用
x0 = [ x2 , z2 , 1 ];
M = fsolve(@mysistem,x0,options);
如果您想通过更改StepTolerance
(默认值1e-6)来降低默认精度。
此外,对于更多的增量,您可能希望使用雅可比矩阵以获得更高的效率。
有关更多参考,请参阅官方文档:
fsolve Nonlinear Equations with Analytic Jacobian
基本上为解算器提供系统的雅可比矩阵(以及特殊选项),可以提高方法效率。