Этот пример показов, как решить нелинейный метод наименьших квадратов задачу двумя способами. Пример сначала решает задачу, не используя якобианскую функцию. Затем показано, как включить якобиан, и иллюстрирует полученную в результате улучшенную эффективность.
Задача имеет 10 членов с двумя неизвестными: найти x, двумерный вектор, который минимизирует
начиная с точки x0 = [0.3,0.4]
.
Потому что lsqnonlin
принимает, что сумма квадратов явно не сформирована в пользовательской функции, функция передана в lsqnonlin
необходимо вычислить векторную функцию
для k = 1 до 10 (то есть F должен иметь 10 компонентов).
Функция помощника myfun
заданный в конце этого примера реализует векторно оцененную целевую функцию без информации о производной. Решить минимизацию начиная с точки x0
.
x0 = [0.3,0.4]; % Starting guess [x,resnorm,res,eflag,output] = lsqnonlin(@myfun,x0); % Invoke optimizer
Local minimum possible. lsqnonlin stopped because the size of the current step is less than the value of the step size tolerance.
Исследуйте решение и количество вычислений функции.
disp(x)
0.2578 0.2578
disp(resnorm)
124.3622
disp(output.funcCount)
72
Целевая функция достаточно проста, чтобы можно было вычислить ее якобиан. Следуя определению в якобианах Вектора Functions, якобианская функция представляет матрицу
Вот, является k-м компонентом целевой функции. Этот пример имеет
так
Функция помощника myfun2
заданный в конце этого примера реализует целевую функцию с якобианом. Установите опции, чтобы решатель использовал якобиан.
opts = optimoptions(@lsqnonlin,'SpecifyObjectiveGradient',true);
Запустите решатель.
lb = []; % No bounds
ub = [];
[x2,resnorm2,res2,eflag2,output2] = lsqnonlin(@myfun2,x0,lb,ub,opts);
Local minimum possible. lsqnonlin stopped because the size of the current step is less than the value of the step size tolerance.
Решение аналогично предыдущему решению.
disp(x2)
0.2578 0.2578
disp(resnorm2)
124.3622
Преимущество использования якобиана в том, что решатель принимает намного меньше вычислений функции.
disp(output2.funcCount)
24
Этот код создает myfun
вспомогательная функция.
function F = myfun(x) k = 1:10; F = 2 + 2*k-exp(k*x(1))-exp(k*x(2)); end
Этот код создает myfun2
вспомогательная функция.
function [F,J] = myfun2(x) k = 1:10; F = 2 + 2*k-exp(k*x(1))-exp(k*x(2)); if nargout > 1 J = zeros(10,2); J(k,1) = -k.*exp(k*x(1)); J(k,2) = -k.*exp(k*x(2)); end end