Только в том случае, уравнение ваш фактическое уравнения (а не фиктивный пример): что уравнение линейного, смысл, вы можете решить для всех 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
... вы знаете, что это линейные уравнения, не так ли? Вам не нужно 'fsolve' решать те, на самом деле, которые будут довольно медленными и, вполне возможно, неточными ... это пример' root' или ваша * реальная * функция для решения? –