lsqcurvefit
или lsqnonlin
Этот пример показывает, как сгенерировать код С для нелинейных методов наименьших квадратов.
В этом примере вектор xdata
представляет 100 точек данных и вектор ydata
представляет связанные измерения. Смоделированная связь между xdata
и ydata
является
Сгенерируйте данные для задачи.
rng(5489,'twister') % For reproducibility xdata = -2*log(rand(100,1)); ydata = (ones(100,1) + .1*randn(100,1)) + (3*ones(100,1)+... 0.5*randn(100,1)).*exp((-(2*ones(100,1)+... 0.5*randn(100,1))).*xdata);
Код генерирует xdata
из 100 независимых выборок экспоненциального распределения со средним 2. Код генерирует ydata
из своего определяющего уравнения используя a = [1;3;2]
, возмущается добавлением нормальных отклонений со стандартными отклонениями [0.1;0.5;0.5]
.
lsqcurvefit
Цель состоит в том, чтобы найти параметры для модели , i = 1, 2, 3, которые лучше всего соответствуют данным.
Для подгонки параметров к данным используя lsqcurvefit
необходимо задать функцию аппроксимации. Для lsqcurvefit
Функция аппроксимации принимает вектор параметра a
и данные xdata
и возвращает предсказание отклика, которое должно быть равно ydata
без шума и идеальной модели. Определите функцию аппроксимации predicted
как анонимная функция.
predicted = @(a,xdata) a(1)*ones(100,1)+a(2)*exp(-a(3)*xdata);
Чтобы соответствовать модели данным, lsqcurvefit
нужна начальная оценка a0
параметров.
a0 = [2;2;2];
Звонить lsqcurvefit
чтобы найти оптимальные параметры .
[ahat,resnorm,residual,exitflag,output,lambda,jacobian] =...
lsqcurvefit(predicted,a0,xdata,ydata);
Чтобы решить ту же проблему с помощью генерации кода, выполните следующие шаги.
Напишите функцию, которая включает все предыдущие шаги: сгенерируйте данные, создайте функцию аппроксимации, создайте начальную точку и вызовите lsqcurvefit
.
function [x,res] = solvelsqcurve rng(5489,'twister') % For reproducibility xdata = -2*log(rand(100,1)); ydata = (ones(100,1) + .1*randn(100,1)) + (3*ones(100,1)+... 0.5*randn(100,1)).*exp((-(2*ones(100,1)+... 0.5*randn(100,1))).*xdata); predicted = @(a,xdata) a(1)*ones(100,1)+a(2)*exp(-a(3)*xdata); options = optimoptions('lsqcurvefit','Algorithm','levenberg-marquardt','Display','off'); a0 = [2;2;2]; lb = []; ub = []; [x,res] = lsqcurvefit(predicted,a0,xdata,ydata,lb,ub,options); end
Создайте строение для генерации кода. В этом случае используйте 'mex'
.
cfg = coder.config('mex');
Сгенерируйте код для solvelsqcurve
функция.
codegen -config cfg solvelsqcurve
Протестируйте сгенерированный код, запустив сгенерированный файл с именем solvelsqcurve_mex.mexw64
или аналогичный.
[x,res] = solvelsqcurve_mex
x = 1.0169 3.1444 2.1596 res = 7.4101
lsqnonlin
Цель состоит в том, чтобы найти параметры для модели , i = 1, 2, 3, которые лучше всего соответствуют данным.
Для подгонки параметров к данным используя lsqnonlin
необходимо задать функцию аппроксимации. Для lsqnonlin
Функция аппроксимации принимает вектор параметра a
, данные xdata
и данные ydata
. Функция аппроксимации возвращает различие между предсказанием отклика и данными ydata
, который должен равняться 0 без шума и идеальной модели. Определите функцию аппроксимации predicted
как анонимная функция.
predicted = @(a)(a(1)*ones(100,1)+a(2)*exp(-a(3)*xdata) - ydata)
Чтобы соответствовать модели данным, lsqnonlin
нужна начальная оценка a0
параметров.
a0 = [2;2;2];
Звонить lsqnonlin
чтобы найти оптимальные параметры .
[ahat,resnorm,residual,exitflag,output,lambda,jacobian] =...
lsqnonlin(predicted,a0);
Чтобы решить ту же проблему с помощью генерации кода, выполните следующие шаги.
Напишите функцию, которая включает все предыдущие шаги: сгенерируйте данные, создайте функцию аппроксимации, создайте начальную точку и вызовите lsqnonlin
.
function [x,res] = solvelsqnon rng(5489,'twister') % For reproducibility xdata = -2*log(rand(100,1)); ydata = (ones(100,1) + .1*randn(100,1)) + (3*ones(100,1)+... 0.5*randn(100,1)).*exp((-(2*ones(100,1)+... 0.5*randn(100,1))).*xdata); predicted = @(a) (a(1)*ones(100,1)+a(2)*exp(-a(3)*xdata) - ydata); options = optimoptions('lsqnonlin','Algorithm','levenberg-marquardt','Display','off'); a0 = [2;2;2]; lb = []; ub = []; [x,res] = lsqnonlin(predicted,a0,lb,ub,options); end
Создайте строение для генерации кода. В этом случае используйте 'mex'
.
cfg = coder.config('mex');
Сгенерируйте код для solvelsqnon
функция.
codegen -config cfg solvelsqnon
Протестируйте сгенерированный код, запустив сгенерированный файл с именем solvelsqnon_mex.mexw64
или аналогичный.
[x,res] = solvelsqnon_mex
x = 1.0169 3.1444 2.1596 res = 7.4101
Решение идентично решению, сгенерированному solvelsqcurve_mex
потому что решатели имеют одинаковые базовые алгоритмы. Таким образом, вы можете использовать решатель, который вы находите наиболее удобным.
lsqcurvefit
| lsqnonlin
| optimoptions
| codegen
(MATLAB CODER)