lsqcurvefit или lsqnonlinВ этом примере показано, как создать код C для нелинейных наименьших квадратов.
В этом примере вектор xdata представляет 100 точек данных, а вектор ydata представляет связанные измерения. Смоделированная взаимосвязь между xdata и ydata является
a3xdatai) + αi.
Создайте данные для проблемы.
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, 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 для поиска наиболее подходящих параметров i.
[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.4101lsqnonlinЦель состоит в том, чтобы найти параметры для модели i, 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 для поиска наиболее подходящих параметров i.
[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)