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

Входные данные,
ответ и
комплексный вектор коэффициентов. Цель состоит в том, чтобы оценить
от
и шумные наблюдения
. Модель данных аналитична, таким образом, можно использовать ее в сложном решении.
Сгенерируйте искусственные данные для модели. Возьмите комплексный вектор коэффициентов
в качестве [2;3+4i;-.5+.4i]. Возьмите наблюдения
, как экспоненциально распределено. Добавьте шум с комплексным знаком в ответы
.
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 для
и ответ cplxydata для
):
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, запишите модель, чтобы дать только ответы, не ответы минус данные об ответе.
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, потому что базовые алгоритмы идентичны. Используйте, какой бы ни решатель вы находите более удобными.
Чтобы включать границы, или просто остаться полностью в действительных значениях, можно разделить действительные и комплексные части коэффициентов в отдельные переменные. Для этой проблемы, разделение коэффициенты можно следующим образом:

Запишите функцию отклика для 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 с шестью элементами как трехэлементный комплексный вектор, и вы видите, что решение является фактически тем же самым как предыдущими решениями.