Шаг 1: Запишите файл myfun.m, который вычисляет значения целевой функции.
Шаг 2: Вызовите стандартную программу нелинейного метода наименьших квадратов.
Этот пример показывает, как решить проблему нелинейного метода наименьших квадратов двумя способами. Это сначала показывает решение, не используя Функцию Якоби. Затем это показывает, как включать якобиан, и это показывает улучшение эффективности, что якобиан дает.
Проблема имеет 10 условий с 2 неизвестными: найдите x, двумерный вектор, который минимизирует
запуск в точке x0 = [0.3,0.4]
.
Поскольку lsqnonlin
принимает, что сумма квадратов явным образом не формируется в функции пользователя, функция, переданная lsqnonlin
, должна вычислить вектор оцененная функция
для k = 1 - 10 (то есть, F
должен иметь 10 компонентов).
function F = myfun(x) k = 1:10; F = 2 + 2*k-exp(k*x(1))-exp(k*x(2));
x0 = [0.3,0.4]; % Starting guess [x,resnorm,res,eflag,output1] = lsqnonlin(@myfun,x0); % Invoke optimizer
Поскольку якобиан не вычисляется в myfun.m
, lsqnonlin
вызывает доверительную область отражающий алгоритм с полным конечным дифференцированием. Обратите внимание на то, что опция SpecifyObjectiveGradient
в options
установлена в false
по умолчанию.
После 72 функциональных оценок этот пример дает решение
x,resnorm x = 0.2578 0.2578 resnorm = 124.3622
Большинство компьютерных систем может решить намного большие полные проблемы, сказать в сотни уравнений и переменных. Но если существует некоторая структура разреженности в якобиане (или Гессиан), который может быть использован в своих интересах, крупномасштабные методы всегда запускается быстрее, если эта информация предоставляется.
Целевая функция достаточно проста вычислить свой якобиан. После определения в Якобианах Вектор-функций Функция Якоби представляет матрицу
Здесь, Fk (x является k th компонент целевой функции. Этот пример имеет
так
Измените файл целевой функции.
function [F,J] = myfun(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
Установите опции, таким образом, решатель использует якобиан.
opts = optimoptions(@lsqnonlin,'SpecifyObjectiveGradient',true);
Запустите решатель.
x0 = [0.3 0.4]; % Starting guess [x,resnorm,res,eflag,output2] = lsqnonlin(@myfun,x0,[],[],opts);
Решение эквивалентно прежде.
x,resnorm x = 0.2578 0.2578 resnorm = 124.3622
Преимущество для использования якобиана состоит в том, что решатель берет меньше функциональных оценок, 24 вместо 72.
[output1.funcCount,output2.funcCount] ans = 72 24