主要内容

本页采用了机器翻译。点击此处可查看英文原文。

对复数值数据进行模型拟合

此示例说明如何对复数值数据执行非线性拟合。虽然大多数 Optimization Toolbox™ 求解器和算法只能处理实数值数据,但最小二乘求解器和 fsolve 可以处理无约束问题的实数值和复数值数据。目标函数必须为复函数意义上的解析函数。

使用复数数据时,请不要将 FunValCheck 选项设置为 "on"。求解器出错。请不要将 "interior-point" 算法与 lsqcurvefitlsqnonlin 结合使用;此算法主要用于处理约束,但尚未经过验证是否能够处理复数数据。代码生成无法处理复数数据。

数据模型

以下数据模型是一个简单的指数:

y(x)=v1+v2ev3x.

x 是输入数据,y 是响应,v 是由系数组成的复数值向量。目标是基于 x 和噪声观测值 y 估计 v。该数据模型是解析模型,因此您可以将它用于复杂的求解。

含噪人工数据

为模型生成人工数据。将复系数向量 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;  

拟合模型以恢复系数向量

数据模型预测的响应与观测值之间的差异(xxdatay 为响应 cplxydata)为:

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

使用 lsqnonlinlsqcurvefit 对数据进行模型拟合。此示例首先使用 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 = 3×1 complex

   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 = 3×1 complex

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

resnorm = 
100.9933

结果与使用 lsqnonlin 得到的结果匹配,因为底层算法是相同的。使用您认为更方便的求解器。

替代方法:拆分实部和虚部

为了包括边界,或简单地完全保持在实数值内,您可以将系数的实部和复部拆分成单独的变量。对于此问题,拆分系数如下:

y=v1+iv2+(v3+iv4)exp((v5+iv6)x)=(v1+v3exp(v5x)cos(v6x)-v4exp(v5x)sin(v6x))+i(v2+v4exp(v5x)cos(v6x)+v3exp(v5x)sin(v6x)).

编写 lsqcurvefit 的响应函数。

<include>cplxreal.m</include>

将以下代码保存为 MATLAB® 路径下的文件 cplxreal.m

将响应数据拆分为实部和虚部。

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

系数向量 v 现在有六个维度。将其初始化为全部为一的值,并使用 lsqcurvefit 求解问题。

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

<stopping criteria details>
vestimated,resnorm,exitflag,output.firstorderopt 
vestimated = 6×1

    2.1582
    0.1351
    2.7399
    3.8012
   -0.5338
    0.4660

resnorm = 
100.9933
exitflag = 
3
ans = 
0.0018

将六元素向量 vestimated 解释为三元素复数向量,您会发现该解实际上与之前的解相同。

另请参阅

主题