В этом примере показано, как решить задачу нелинейного метода наименьших квадратов двумя способами. Пример сначала решает задачу, не используя Функцию Якоби. Затем это показывает, как включать якобиан и иллюстрирует получившуюся повышенную эффективность.
Проблема имеет 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
Целевая функция достаточно проста, что можно вычислить ее якобиан. После определения в Якобианах Вектор-функций Функция Якоби представляет матрицу
Здесь, 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