FuncFit thinks complex y wave and real x wave have a different number of points
Hi all,
I'm trying to write an all-at-once fitting function for a frequency-domain measurement. I'm trying to use a 62-data-point complex y wave and a 62-data-point real-only x wave as the input, but I get an error saying that the x and y data contain a different number of points. Any ideas?
In the following code, I split up the output from the instrument (5 columns: frequency, X channel signal, error in X channel, Y channel signal, error in Y channel) into a wave for the x data (wF, the frequencies used) and the real and imaginary components of the signal (wX and wY, respectively), which get combined into a 1-dimensional complex-valued wave, wComplex. I then try to pass the complex-valued wComplex as the y data and wF as the x data for FitFunc, but it gives me the error, "error: X and Y data have different number of points."
I also wrote it to fit as the log of the function thinking it would save time, but honestly, even having 50000 simulated points in the all-at-once function is pretty fast, hence the weird shenanigans with the log and 10^x stuff.
Function SSMC_FreqFit(w0,wParam)
WAVE w0,wParam
Duplicate/FREE/O/R=[][0] w0, wF
Duplicate/FREE/O/R=[][1] w0, wX
Duplicate/FREE/O/R=[][3] w0, wY
Variable NumFreqs = DimSize(w0,0)
Make/C/O/N=(NumFreqs) wComplex
wComplex[] = cmplx(wX[p],wY[p])
String CFitName = NameOfWave(w0) + "_CFit"
Duplicate/O wComplex,$CFitName
WAVE wCFit = $CFitName
WAVE ParamTable
WAVE ParamHold
String HoldStr = num2str(ParamHold[0]) + num2str(ParamHold[1]) + num2str(ParamHold[2]) + num2str(ParamHold[3]) + num2str(ParamHold[4]) + num2str(ParamHold[5]) + num2str(ParamHold[6]) + num2str(ParamHold[7]) + num2str(ParamHold[8])
FuncFit/H=HoldStr SSMC_FreqFit_proc, ParamTable, wComplex /X=wF/D=wCFit
String ParamOut = NameOfWave(w0) + "_Param"
String ParamSOut = ParamOut + "_s"
Duplicate/O wParam,$ParamOut
WAVE W_sigma
Duplicate/O W_sigma,$ParamSOut
WAVE wParamOut = $ParamOut
WAVE wParamSOut = $ParamSOut
String OutName = NameOfWave(w0) + "_Fit"
Duplicate/O w0,$OutName
WAVE wOut = $OutName
wOut[][0] = w0[p][0]
wOut[][1] = real(wCFit[p])
wOut[][2] = 0
wOut[][3] = imag(wCFit[p])
wOut[][4] = 0
End
Function SSMC_FreqFit_Proc(wcoef, yw, xw) :FitFunc
WAVE wcoef
WAVE/C yw
WAVE xw
Variable A0 = wcoef[0]
Variable t0 = wcoef[1]
Variable A1 = wcoef[2]
Variable t1 = wcoef[3]
Variable A2 = wcoef[4]
Variable t2 = wcoef[5]
Variable F0 = Log(wcoef[6])
Variable F1 = Log(wcoef[7])
Variable Sig = wcoef[8]
Variable Res = 0.0001
Make/O/N=(F1/Res-F0/Res,5)/FREE wFit
SetScale/p x F0,Res,"",wFit
wFit[][0] = 10^x
wFit[][1] = Sig*(A0*t0/(1+(2*pi*10^x)^2*t0^2)+A1*t1/(1+(2*pi*10^x)^2*t1^2)+A2*t2/(1+(2*pi*10^x)^2*t2^2))/(A0*t0+A1*t1+A2*t2)
wFit[][2] = 0
wFit[][3] = -Sig*(A0*(2*pi*10^x)*t0^2/(1+(2*pi*10^x)^2*t0^2)+A1*(2*pi*10^x)*t1^2/(1+(2*pi*10^x)^2*t1^2)+A2*(2*pi*10^x)*t2^2/(1+(2*pi*10^x)^2*t2^2))/(A0*t0+A1*t1+A2*t2)
wFit[][4] = 0
Duplicate/O/FREE/R=[][0] wFit, SimFreqs
Duplicate/O/FREE/R=[][1] wFit, SimX
Duplicate/O/FREE/R=[][3] wFit, SimY
yw[] = cmplx(interp(xw[p],SimFreqs,SimX),interp(xw[p],SimFreqs,SimY))
End
Update: easy solution. Make the frequency wave complex also but just leave the imaginary component as 0.
October 2, 2025 at 03:39 pm - Permalink
I think the combination of complex Y and real X should work. Could you post an experiment file? Complex fitting is pretty new and hardly used by anyone, so it hasn't had problems shaken out yet.
October 2, 2025 at 05:18 pm - Permalink