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
находит намного лучшее решение, чем локальный решатель один.