Fit complex waves
rvaldes
The complex function is something like this
A/(1-I*x*D)-B*I*x/(h^2-x^2-I*x*G)-I*x*C
where the parameters to fit are: A,B,C,D,G and all are real. h is a fixed real number. x has the usual Igor meaning.
Thanks
Wave w
variable xx
variable/c theVal
theVal = w[0]/(cmplx(1, -xx * w[3]) + cmplx(0, -w[1] * xx) / cmplx(w[5]^2-x^2, -xx*w[4])+cmplx(0, -xx*w[2])
return theVal
End
Threadsafe Function realPart(w, yy, xx):fitfunc
Wave w, yy, xx
multithread yy = real(getTheValue(w, xx))
End
Threadsafe Function cmplxPart(w, yy, xx):fitfunc
Wave w, yy, xx
multithread yy = imag(getTheValue(w, xx))
End
THen separate the dependent data into real and imaginary waves:
make/n=(numpnts(mydata)) theRealData, theImagData
theRealData = real(mydata)
theImagData = imag(myData)
Then use global fit to fit the two datasets. Use the realPart function to fit the real part of the data and the imagPart function to fit the imaginary part of the data. Both functions will have 6 parameters and you have to link all the parameters for the fit.
January 12, 2011 at 10:06 pm - Permalink
I tested andyfaff's code and it works as described. This is a very convenient way to solve the problem of fitting a complex function if you cannot easily seperate your function by hand. However, if time is an issue, note that it computes at roughly half the speed as a pre-seperated version of the same function. I seperated your function using mathematica, however, the same result could be obtained by using the complex conjugate.
Realpart=A/(1 + D^2*x^2) + (B*G*x^2)/(G^2*x^2 + (h^2 - x^2)^2)
Imagpart=(-(C*x) + (A*D*x)/(1 + D^2*x^2) - (B*h^2*x)/(G^2*x^2 + (h^2 - x^2)^2) + (B*x^3)/(G^2*x^2 + (h^2 - x^2)^2))
good luck!
May 6, 2011 at 02:17 am - Permalink
2 * w[0] * cmplx(w[1], xx * w[3]) * tanh(w[4] * sqrt((w[0] * w[2] * cmplx(w[1], xx * w[3]))/(w[3] * w[4] * w[5]))/2)/(w[3] * w[4] * sqrt((w[0] * w[2] * cmplx(w[1], xx * w[3]))/(w[3] * w[4] * w[5])))
It is not easily separable (it requires argument functions to calculate the modulus squared). I have been trying to adapt the above code provided by the first reply with no success. Here is my code:
#pragma rtGlobals=1 // Use modern global access method.
Threadsafe Function/c getTheValue(w, xx)
Wave w
variable xx
variable/c theVal
theVal = 2 * w[0] * cmplx(w[1], xx * w[3]) * tanh(w[4] * sqrt((w[0] * w[2] * cmplx(w[1], xx * w[3]))/(w[3] * w[4] * w[5]))/2)/(w[3] * w[4] * sqrt((w[0] * w[2] * cmplx(w[1], xx * w[3]))/(w[3] * w[4] * w[5])))
return theVal
End
Threadsafe Function realPart(w, yy, xx):fitfunc
Wave w, yy, xx
multithread yy = real(getTheValue(w, xx))
End
Threadsafe Function cmplxPart(w, yy, xx):fitfunc
Wave w, yy, xx
multithread yy = imag(getTheValue(w, xx))
End
It compiles without issue. I notice that when choosing the fit functions in the Global Fit window, the parameters I provide in the function do not appear and I have to manually input the #coefs. When I attempt to run the fit, I get an immediate response: "Global fit is running the template fitting function for some reason". When it completes the attempt, I get the error message : "The fitting function returned NaN for at least one X value". My data is already in separate waves for the real and imaginary part. Any help would be deeply appreciated
October 12, 2011 at 03:27 pm - Permalink
John Weeks
WaveMetrics, Inc.
support@wavemetrics.com
October 12, 2011 at 04:14 pm - Permalink
October 12, 2011 at 05:17 pm - Permalink