以防万一该方程式是您的实际方程式(而不是虚拟示例):该方程式是线性,这意味着您可以解决所有v用一个简单的mldivide:
v = sort(rand(1,1000));
x = [1 1; 1 -1] \ bsxfun(@plus, -v, [2; 1.8])
而且,如果这些不是你的实际方程,你不需要循环,你可以向量化整个事情:
function x = solver()
options = optimset('Display' , 'off',...
'MaxFunEvals', 1e5,...
'MaxIter' , 1e4);
v = sort(rand(1, 1000));
x0 = repmat([0 0], numel(v), 1);
x = fsolve(@(x)root(x,v'), x0, options);
end
function D = root(x,v)
D = [x(:,1) + x(:,2) + v - 2
x(:,1) - x(:,2) + v - 1.8];
end
这可能会也可能不会比循环更快,这取决于您的实际方程式。
它可能会更慢,因为fsolve 需要计算 2000×2000(4M 元素)的雅可比行列式,而不是 2×2、1000 次(4k 元素)。
但是,它可能会更快,因为fsolve 的启动成本可能很大,这意味着许多调用的开销实际上可能超过计算更大的雅可比行列式的成本。
无论如何,提供雅可比矩阵作为第二个输出将大大加快一切:
function solver()
options = optimset('Display' , 'off',...
'MaxFunEvals', 1e5,...
'MaxIter' , 1e4,...
'Jacobian' , 'on');
v = sort(rand(1, 1000));
x0 = repmat([1 1], numel(v), 1);
x = fsolve(@(x)root(x,v'), x0, options);
end
function [D, J] = root(x,v)
% Jacobian is constant:
persistent J_out
if isempty(J_out)
one = speye(numel(v));
J_out = [+one +one
+one -one];
end
% Function values at x
D = [x(:,1) + x(:,2) + v - 2
x(:,1) - x(:,2) + v - 1.8];
% Jacobian at x:
J = J_out;
end