exponenta event banner

Подгонка модели к данным со сложным значением

В этом примере показано, как выполнить нелинейную подгонку комплексных данных. В то время как большинство решателей и алгоритмов Optimization Toolbox™ работают только с реальными данными, решатели с наименьшими квадратами и fsolve может работать как с реальными, так и с комплексными данными для неограниченных задач. Целевая функция должна быть аналитической в смысле комплексной функции.

Не устанавливайте FunValCheck опция для 'on' при использовании сложных данных. Ошибки решателя.

Модель данных

Модель данных является простой экспоненциальной:

$$y(x) = v_1 + v_2 e^{v_3 x}.$$

Является$x$ входными данными,$y$ является откликом и является$v$ комплекснозначным вектором коэффициентов. Цель - оценить$v$ по и$x$ шумным наблюдениям. $y$Модель данных является аналитической, поэтому ее можно использовать в сложном решении.

Искусственные данные с шумом

Создание искусственных данных для модели. Взять вектор комплексного коэффициента$v$ как [2;3+4i;-.5+.4i]. Примите наблюдения$x$ как экспоненциально распределенные. Добавление сложного шума к ответам.$y$

rng default % for reproducibility
N = 100; % number of observations
v0 = [2;3+4i;-.5+.4i]; % coefficient vector
xdata = -log(rand(N,1)); % exponentially distributed
noisedata = randn(N,1).*exp((1i*randn(N,1))); % complex noise
cplxydata = v0(1) + v0(2).*exp(v0(3)*xdata) + noisedata;

Подгонка модели для восстановления вектора коэффициентов

Разница между ответом, предсказанным моделью данных, и наблюдением (xdata для$x$ и ответ cplxydata for) $y$является:

objfcn = @(v)v(1)+v(2)*exp(v(3)*xdata) - cplxydata;

Использовать либо lsqnonlin или lsqcurvefit для соответствия модели данным. В этом примере сначала используется lsqnonlin.

opts = optimoptions(@lsqnonlin,'Display','off');
x0 = (1+1i)*[1;1;1]; % arbitrary initial guess
[vestimated,resnorm,residuals,exitflag,output] = lsqnonlin(objfcn,x0,[],[],opts);
vestimated,resnorm,exitflag,output.firstorderopt
vestimated =

   2.1582 + 0.1351i
   2.7399 + 3.8012i
  -0.5338 + 0.4660i


resnorm =

  100.9933


exitflag =

     3


ans =

    0.0018

lsqnonlin восстанавливает вектор комплексного коэффициента примерно до одной значащей цифры. Норма остатка значительна, что указывает на то, что шум удерживает модель от соответствия всем наблюдениям. Флаг выхода: 3, не является предпочтительным 1, потому что мера оптимальности первого порядка 1e-3, не ниже 1e-6.

Альтернатива: использовать lsqcurvefit

Подгонка с помощью lsqcurvefit, написать модель, чтобы дать только ответы, а не ответы минус данные ответа.

objfcn = @(v,xdata)v(1)+v(2)*exp(v(3)*xdata);

Использовать lsqcurvefit параметры и синтаксис.

opts = optimoptions(@lsqcurvefit,opts); % reuse the options
[vestimated,resnorm] = lsqcurvefit(objfcn,x0,xdata,cplxydata,[],[],opts)
vestimated =

   2.1582 + 0.1351i
   2.7399 + 3.8012i
  -0.5338 + 0.4660i


resnorm =

  100.9933

Результаты соответствуют результатам из lsqnonlin, потому что лежащие в основе алгоритмы идентичны. Используйте любой решатель, который будет удобнее.

Альтернатива: Разделить реальные и воображаемые детали

Чтобы включить границы или просто полностью остаться в пределах вещественных значений, можно разделить действительную и сложную части коэффициентов на отдельные переменные. Для этой проблемы разделите коэффициенты следующим образом:

$$ \begin{array}{l}
y = {v_1} + i{v_2} + ({v_3} + i{v_4})\exp \left( {({v_5} + i{v_6})x} \right)\\
\ \ = \left( {{v_1} + {v_3}\exp ({v_5}x)\cos ({v_6}x) - {v_4}\exp ({v_5}x)\sin ({v_6}x)} \right)\\
\ \ + i \left( {{v_2} + {v_4}\exp ({v_5}x)\cos ({v_6}x) + {v_3}\exp ({v_5}x)\sin ({v_6}x)} \right).
\end{array}$$

Записать функцию ответа для lsqcurvefit.

function yout = cplxreal(v,xdata)

yout = zeros(length(xdata),2); % allocate yout

expcoef = exp(v(5)*xdata(:)); % magnitude
coscoef = cos(v(6)*xdata(:)); % real cosine term
sincoef = sin(v(6)*xdata(:)); % imaginary sin term
yout(:,1) = v(1) + expcoef.*(v(3)*coscoef - v(4)*sincoef);
yout(:,2) = v(2) + expcoef.*(v(4)*coscoef + v(3)*sincoef);

Сохранить этот код как файл cplxreal.m на пути MATLAB ®.

Разбейте данные ответа на реальные и мнимые части.

ydata2 = [real(cplxydata),imag(cplxydata)];

Вектор коэффициентов v теперь имеет шесть измерений. Инициализировать его как все и решить проблему с помощью lsqcurvefit.

x0 = ones(6,1);
[vestimated,resnorm,residuals,exitflag,output] = ...
    lsqcurvefit(@cplxreal,x0,xdata,ydata2);
vestimated,resnorm,exitflag,output.firstorderopt
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.


vestimated =

    2.1582
    0.1351
    2.7399
    3.8012
   -0.5338
    0.4660


resnorm =

  100.9933


exitflag =

     3


ans =

    0.0018

Интерпретировать шестиэлементный вектор vestimated как трехэлементный комплексный вектор, и вы видите, что решение практически совпадает с предыдущими решениями.

Связанные темы