when running lsqcurvefit to fit the complex function: F = a1*exp(-1i*x*a2) + a3*exp(-1i*x*a4), i get a2 and a4 as complex estimates, however these values should be real. how to solve this?
8 次查看(过去 30 天)
显示 更早的评论
when runing lsqcurvefit to fit the complex function: F = a1*exp(-1i*x*a2) + a3*exp(-1i*x*a4), i get a2 and a4 as complex estimates, however these values should be real. how to solve this?
0 个评论
回答(4 个)
Walter Roberson
2017-12-15
lsqcurvefit defines that the xdata and ydata must be real valued. In your model
F = a1*exp(-1i*x*a2) + a3*exp(-1i*x*a4)
with x and a2 and a4 real-valued, -1i*x*a2 and -1i*x*a4 are guaranteed to be complex valued (or 0), and exp() of a complex value is complex.
If a1 and a2 are real-valued then the two summands would be complex, and it is quite unlikely that their imaginary components will exactly balance out to give a real value -- but ydata must be real.
If a1 and a2 are complex valued then although it is possible for the a1*exp() terms and a3*exp() terms to happen to be real-valued, it is not likely.
If you are counting on complex components happening to cancel out or happening to multiply to give real values, you should probably be using a different formulation of your model.
3 个评论
Walter Roberson
2017-12-15
Please describe more clearly what you want to do.
Are you trying to find real-valued a1, a2, a3, a4, with real-valued x and y, such that
a1*exp(-1i*x*a2) + a3*exp(-1i*x*a4) - y
is real-valued ? So, in other words,
imag(a1*exp(-1i*x*a2)) == -imag(a3*exp(-1i*x*a4))
so that the imaginary part exactly cancels to 0?
Matt J
2017-12-15
编辑:Matt J
2017-12-15
Convert F to an equivalent real-valued function (but with higher dimensional output) as follows,
F_modified=@(a,xdata) [real(F(a,xdata(:))) ; imag(F(a,xdata(:)))];
Similarly, convert your ydata to a real equivalent,
ydata_modified = [real(ydata(:)); imag(ydata(:))];
Pass the modified inputs to lsqcurvefit in place of the original.
11 个评论
Torsten
2017-12-18
Write your function F as
y = (a11+1i*a12)*(cos(a2*xdata)-1i*sin(a2*xdata))+(a31+1i*a32)*(cos(a4*xdata)-1i*sin(a4*xdata)) =
(a11*cos(a2*xdata)+a12*sin(a2*xdata)+a31*cos(a4*xdata)+a32*sin(a4*xdata))+1i*(-a11*sin(a2*xdata)+a12*cos(a2*xdata)-a31*sin(a4*xdata)+a32*cos(a4*xdata))
and fit simultaneously real(ydata) against
a11*cos(a2*xdata)+a12*sin(a2*xdata)+a31*cos(a4*xdata)+a32*sin(a4*xdata)
and imag(ydata) against
-a11*sin(a2*xdata)+a12*cos(a2*xdata)-a31*sin(a4*xdata)+a32*cos(a4*xdata)
Best wishes
Torsten.
4 个评论
Torsten
2017-12-20
编辑:Torsten
2017-12-20
I used lsqnonlin because the handling of xdata and ydata is easier.
To use "lsqcurvefit", you will have to double "xdata" as
Xdata = [xdata,xdata];
,supply the corresponding ydata as
Ydata = [real(ydata),imag(ydata)];
and call "lsqcurvefit" as
x = lsqcurvefit(@fun,x0,Xdata,Ydata);
Further, you will have to change res because the subtraction of rydata and iydata is no longer necessary.
From the numerical point of view, both solvers are equivalent ; only the Interface is a bit different.
Best wishes
Torsten.
另请参阅
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!