Как построить косинусоидальную волну в MATLAB с учетом подгоночных параметров? - PullRequest
1 голос
/ 28 февраля 2020

В моем проекте я использовал обобщенную c косинусную функцию для подгонки моих данных:

cos_fun = @(p, theta) p(1) + p(2) * cos(theta - p(3))

p = nlinfit(x,y,cos_fun,[1 1 0])

В результате p имеет три значения: смещение по оси y, амплитуду и фазу .

Можно ли нарисовать гладкую косинусную кривую, используя эти три параметра?

1 Ответ

3 голосов
/ 28 февраля 2020

TL; DR: Можно как подогнать, так и построить кривую, с использованием и без использования наборов инструментов. Все случаи представлены ниже.


Plotting

Построение графика функции следует непосредственно из функции, используемой для получения ваших параметров с использованием plot(). Обратите внимание, что вы управляете сглаживанием построенной функции на основе размера шага для домена (см. step ниже).

На рисунке результаты, полученные из nlinfit() ( Требуется набор инструментов ), аналогичны "SSE", полученным без набора инструментов с использованием fminsearch().

Plot comparing fitted functions to the data. No toolbox required.

% Plot   (No toolbox Required)
step = 0.01;                  % smaller is smoother
Xrng = 0:step:12;

figure, hold on, box on
plot(Xdata,Ydata,'b.','DisplayName','Data')
plot(Xrng,cos_fun(p_SSE,Xrng),'r--','DisplayName','SSE')
plot(Xrng,cos_fun(p_SAE,Xrng),'k--','DisplayName','SAE')
legend('show')

Как указано в комментарии @ Daniel , вы также можете сделать график с nlintool(), но для этого требуется набор инструментов статистики .

nlintool(Xdata,Ydata,cos_fun,[1 1 0])         % toolbox required

Plot comparing fitted functions to the data. No toolbox required.


Установка

Использование nlinfit(): (Требуется панель инструментов статистики)

pNL = nlinfit(Xdata,Ydata,cos_fun,[1 1 0])       % same as SSE approach below

Подход без инструментов:
Вы можете построить функцию выпуклой ошибки, чтобы минимизировать и вернуть глобальный оптимум, используя fminsearch() как пух и грязный подход. Например, сумма квадратов ошибок или сумма абсолютных ошибок будет выпуклым .

% MATLAB R2019a
% Generate Example Data
sigma = 0.5;                   % increase this for more variable data (more noise)
Xdata = [repmat(1:10,1,4)].';
Ydata = cos(Xdata)+sigma*randn(length(Xdata),1);

% Function Evaluation
cos_fun=@(p,x) p(1) + p(2).*cos(x-p(3));

% Error Functions
SSEh =@(p) sum((cos_fun(p,Xdata)-Ydata).^2);   % sum of squared error
SAEh =@(p) sum(abs(cos_fun(p,Xdata)-Ydata));   % sum of absolute error

Конечно, это приведет к различным ошибкам для одного и того же параметра.

% Test
SSEh([1 1 0])
SAEh([1 1 0])

Но затем вы вызываете fminsearch() с начальным предположением параметров p0, чтобы получить параметры, которые минимизируют выбранную вами функцию ошибки. Поскольку SSEh и SAEh являются выпуклыми относительно p, нет необходимости делать это несколько раз и сохранять лучший, поскольку для каждого p0 вы получите один и тот же ответ.

p0 = [1 1 0.25];     % Initial starting point
[p_SSE, SSE] = fminsearch(SSEh,p0)             
[p_SAE, SAE] = fminsearch(SAEh,p0)

Вы подбираете немного разные кривые в зависимости от функции ошибки.

Обратите внимание, что SSEh(pNL) и SSEh(p_SSE) одинаковы, поскольку pNL равно p_SSE, поскольку nlinfit() оценивает коэффициенты "с использованием итеративной оценки наименьших квадратов".

...