Подбор модели к комплексно-оцененным данным

Этот пример показывает, как выполнить нелинейный подбор кривой комплексных данных. В то время как большинство решателей 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 отклика для) $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 как трехэлементный комплексный вектор, и вы видите, что решение фактически совпадает с предыдущими решениями.

Похожие темы