lsqcurvefit
или lsqnonlin
Этот пример показывает, как соответствовать функции к данным с помощью lsqcurvefit
вместе с MultiStart
. Конец примера показывает то же решение с помощью lsqnonlin
.
Много подходящих проблем имеют несколько локальных решений. MultiStart
может помочь найти глобальное решение, означая лучшую подгонку. Этот пример сначала использует lsqcurvefit
из-за своего удобного синтаксиса.
Модель
где входные данные , и параметры , , , и неизвестные коэффициенты модели.
Запишите анонимную функцию, которая берет матрицу данных xdata
со строками N
и двумя столбцами, и возвращает вектор отклика со строками N
. Функция также берет матрицу коэффициентов p
, соответствуя вектору коэффициентов .
fitfcn = @(p,xdata)p(1) + p(2)*xdata(:,1).*sin(p(3)*xdata(:,2)+p(4));
Создайте 200 точек данных и ответы. Используйте значения . Включайте случайный шум в ответ.
rng default % For reproducibility N = 200; % Number of data points preal = [-3,1/4,1/2,1]; % Real coefficients xdata = 5*rand(N,2); % Data points ydata = fitfcn(preal,xdata) + 0.1*randn(N,1); % Response data with noise
Установите границы для lsqcurvefit
. Нет никакой причины превысить в абсолютном значении, потому что синусоидальная функция принимает значения в своем полном спектре на любом интервале ширины . Примите что коэффициент должно быть меньшим, чем 20 в абсолютном значении, потому что разрешение высокой частоты может вызвать нестабильные ответы или неточную сходимость.
lb = [-Inf,-Inf,-20,-pi]; ub = [Inf,Inf,20,pi];
Установите начальную точку произвольно на (5,5,5,0).
p0 = 5*ones(1,4); % Arbitrary initial point p0(4) = 0; % Ensure the initial point satisfies the bounds
Соответствуйте параметрам к данным, запускающимся в p0
.
[xfitted,errorfitted] = lsqcurvefit(fitfcn,p0,xdata,ydata,lb,ub)
Local minimum possible. lsqcurvefit stopped because the final change in the sum of squares relative to its initial value is less than the value of the function tolerance.
xfitted = 1×4
-2.6149 -0.0238 6.0191 -1.6998
errorfitted = 28.2524
lsqcurvefit
находит локальное решение, которое не является особенно близко к значениям параметра модели (–3,1/4,1/2,1).
MultiStart
.Создайте структуру задачи, таким образом, MultiStart
может решить ту же проблему.
problem = createOptimProblem('lsqcurvefit','x0',p0,'objective',fitfcn,... 'lb',lb,'ub',ub,'xdata',xdata,'ydata',ydata);
Решите подходящую проблему с помощью MultiStart
с 50 итерациями. Постройте самую маленькую ошибку как количество итераций MultiStart
.
ms = MultiStart('PlotFcns',@gsplotbestf);
[xmulti,errormulti] = run(ms,problem,50)
MultiStart completed the runs from all start points. All 50 local solver runs converged with a positive local solver exit flag.
xmulti = 1×4
-2.9852 -0.2472 -0.4968 -1.0438
errormulti = 1.6464
MultiStart
находит глобальное решение около значений параметров (–3, –1/4, –1/2, –1). (Это эквивалентно решению около preal
= (–3,1/4,1/2,1), потому что изменение знака всех коэффициентов кроме первого дает те же численные значения fitfcn
.) Норма остаточной ошибки уменьшается от приблизительно 28 до приблизительно 1,6, уменьшения больше, чем фактор 10.
lsqnonlin
Для альтернативного подхода используйте lsqnonlin
в качестве подходящей функции. В этом случае используйте различие между ожидаемыми значениями и фактическими значениями данных как целевая функция.
fitfcn2 = @(p)fitfcn(p,xdata)-ydata; [xlsqnonlin,errorlsqnonlin] = lsqnonlin(fitfcn2,p0,lb,ub)
Local minimum possible. lsqnonlin stopped because the final change in the sum of squares relative to its initial value is less than the value of the function tolerance.
xlsqnonlin = 1×4
-2.6149 -0.0238 6.0191 -1.6998
errorlsqnonlin = 28.2524
Запуская с той же начальной точки p0
, lsqnonlin
находит то же относительно плохое решение как lsqcurvefit
.
Запустите MultiStart
с помощью lsqnonlin
в качестве локального решателя.
problem2 = createOptimProblem('lsqnonlin','x0',p0,'objective',fitfcn2,... 'lb',lb,'ub',ub'); [xmultinonlin,errormultinonlin] = run(ms,problem2,50)
MultiStart completed the runs from all start points. All 50 local solver runs converged with a positive local solver exit flag.
xmultinonlin = 1×4
-2.9852 -0.2472 -0.4968 -1.0438
errormultinonlin = 1.6464
Снова, MultiStart
находит намного лучшее решение, чем локальный решатель один.