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