Filter löschen
Filter löschen

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?

9 Ansichten (letzte 30 Tage)
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?

Antworten (4)

Walter Roberson
Walter Roberson am 15 Dez. 2017
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 Kommentare
Walter Roberson
Walter Roberson am 15 Dez. 2017
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?
joseph chahin
joseph chahin am 16 Dez. 2017
Bearbeitet: Walter Roberson am 16 Dez. 2017
I have a complex data y which should exhibit:
y = a1*exp(-1i*xdata*a2) + a3*exp(-1i*xdata*a4)
where a2 and a4 should be real positive values (a1 and a3 can be complex). Now my function is defined as:
F = myfun(a,xdata)
F = a1*exp(-1i*xdata*a2) + a3*exp(-1i*xdata*a4)
when performing:
[p,resnorm] = lsqcurvefit(@myfun,a0,xdata,(ydata), [],[],opts);
i am getting a2 and a4 as complex values whereas these should be real and positive. please let me know if is not clear? thx.

Melden Sie sich an, um zu kommentieren.


Matt J
Matt J am 15 Dez. 2017
Bearbeitet: Matt J am 15 Dez. 2017
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 Kommentare
joseph chahin
joseph chahin am 22 Dez. 2017
Dear Matt, the real value should always be possitive. shall I set this in LB,UB parameters or is there any option to include this condition in the function F. Thx. Br.

Melden Sie sich an, um zu kommentieren.


YT
YT am 15 Dez. 2017
Bearbeitet: YT am 15 Dez. 2017
I haven't used lsqcurvefit myself, but if you want the real value of a complex number, you can use
a2 = real(a2);
a4 = real(a4);
  1 Kommentar
joseph chahin
joseph chahin am 15 Dez. 2017
what I mean is that the estimate has to be given as real and not complex. this has to be taken into accout in the estimation process.

Melden Sie sich an, um zu kommentieren.


Torsten
Torsten am 18 Dez. 2017
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 Kommentare
joseph chahin
joseph chahin am 20 Dez. 2017
Thanks. I will give it a try. I see that you suggested lsqnonlin, however i am using lsqcurvefit. could you please tell why? does it matter?
Torsten
Torsten am 20 Dez. 2017
Bearbeitet: Torsten am 20 Dez. 2017
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.

Melden Sie sich an, um zu kommentieren.

Kategorien

Mehr zu Computational Geometry finden Sie in Help Center und File Exchange

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by