Hi, I am relatively new to Igor (ie. I am not yet capable of writing decent Igor code). I have a set of complex-valued data (real + I*imaginary) that I would like to fit with a complex function, is this possible?
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.
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.
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.
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
Your two functions need to have the Threadsafe keyword removed. Unfortunately, Global Fit doesn't support threadsafe fitting functions yet. I believe it is OK to use the Multithread keyword inside the functions.
THen separate the dependent data into real and imaginary waves:
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