Fit complex waves
| andyfaff | January 12, 2011 - 22:06 | ||
|---|---|---|---|
|
You can do it, but you have to use Global Fit to do it. Here are the three functions you need: Threadsafe Function/c getTheValue(w, xx) 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: Wave/C mydata 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. |
|||
| mtaylor | May 6, 2011 - 01:17 | ||
|---|---|---|---|
|
Hi, 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! |
|||
| clay | October 12, 2011 - 14:27 | ||
|---|---|---|---|
|
I am trying to fit the following complex function: 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. End Threadsafe Function realPart(w, yy, xx):fitfunc multithread yy = real(getTheValue(w, xx)) Threadsafe Function cmplxPart(w, yy, xx):fitfunc multithread yy = imag(getTheValue(w, xx)) 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 - 15:14 | |||
|---|---|---|---|
|
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. John Weeks |
|||

Joined: 2011-01-12
Location: United States
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.
Thanks