Passing non-waveform X data to all-at-once fitfunc
quoderatmac
Function O70LatPar(q_expt)
Wave q_expt // pass a wave of experimental data
Variable i = 0, j = 0, m = 0, n = 0
Variable index = 1
Variable V_FitError = 4 // suppress progress window
Make/O h = {1,0,0,1,1,1,0,1,2,2,2,0,1} // h, k, and l give 13 allowed reflection planes for orthorhombic lattice
Make/O k = {1,2,0,1,3,1,4,3,0,2,2,4,3}
Make/O l = {1,2,4,3,1,5,0,3,2,0,2,4,5}
Make/O/D latpar = {30,40,70} // lattice parameters--a, b, and c--of unit cell; must find "best fit" values
For (i=0; i<13; i+=1) // for loops solve "13 choose 4" combination problem; that is, all 715 unique combinations of lattice index sets are tried in the fit function
For (j=0; j<i; j+=1)
For (m=0; m<j; m+=1)
For (n=0; n<m; n+=1)
Make/O latind = {{h[i], h[j], h[m], h[n]}, {k[i], k[j], k[m], k[n]}, {l[i], l[j], l[m], l[n]}}
Duplicate/O latind, $("latind"+num2istr(index))
FuncFit/N/Q/NTHR=0 fitting, latpar, q_expt
Duplicate/O latpar, $("fit"+num2istr(index))
Print index, latind // just for debugging
index += 1
Endfor
Endfor
Endfor
Endfor
End
Function fitting(latpar, q_theo, latind) : FitFunc
Wave latpar, q_theo, latind
q_theo[0] = 2*pi*((latind[0]/latpar[0])^2 + (latind[4]/latpar[1])^2 + (latind[8]/latpar[2])^2)^0.5
q_theo[1] = 2*pi*((latind[1]/latpar[0])^2 + (latind[5]/latpar[1])^2 + (latind[9]/latpar[2])^2)^0.5
q_theo[2] = 2*pi*((latind[2]/latpar[0])^2 + (latind[6]/latpar[1])^2 + (latind[10]/latpar[2])^2)^0.5
q_theo[3] = 2*pi*((latind[3]/latpar[0])^2 + (latind[7]/latpar[1])^2 + (latind[11]/latpar[2])^2)^0.5
Print q_theo[0], q_theo[1], q_theo[2], q_theo[3] // just for debugging
End
Wave q_expt // pass a wave of experimental data
Variable i = 0, j = 0, m = 0, n = 0
Variable index = 1
Variable V_FitError = 4 // suppress progress window
Make/O h = {1,0,0,1,1,1,0,1,2,2,2,0,1} // h, k, and l give 13 allowed reflection planes for orthorhombic lattice
Make/O k = {1,2,0,1,3,1,4,3,0,2,2,4,3}
Make/O l = {1,2,4,3,1,5,0,3,2,0,2,4,5}
Make/O/D latpar = {30,40,70} // lattice parameters--a, b, and c--of unit cell; must find "best fit" values
For (i=0; i<13; i+=1) // for loops solve "13 choose 4" combination problem; that is, all 715 unique combinations of lattice index sets are tried in the fit function
For (j=0; j<i; j+=1)
For (m=0; m<j; m+=1)
For (n=0; n<m; n+=1)
Make/O latind = {{h[i], h[j], h[m], h[n]}, {k[i], k[j], k[m], k[n]}, {l[i], l[j], l[m], l[n]}}
Duplicate/O latind, $("latind"+num2istr(index))
FuncFit/N/Q/NTHR=0 fitting, latpar, q_expt
Duplicate/O latpar, $("fit"+num2istr(index))
Print index, latind // just for debugging
index += 1
Endfor
Endfor
Endfor
Endfor
End
Function fitting(latpar, q_theo, latind) : FitFunc
Wave latpar, q_theo, latind
q_theo[0] = 2*pi*((latind[0]/latpar[0])^2 + (latind[4]/latpar[1])^2 + (latind[8]/latpar[2])^2)^0.5
q_theo[1] = 2*pi*((latind[1]/latpar[0])^2 + (latind[5]/latpar[1])^2 + (latind[9]/latpar[2])^2)^0.5
q_theo[2] = 2*pi*((latind[2]/latpar[0])^2 + (latind[6]/latpar[1])^2 + (latind[10]/latpar[2])^2)^0.5
q_theo[3] = 2*pi*((latind[3]/latpar[0])^2 + (latind[7]/latpar[1])^2 + (latind[11]/latpar[2])^2)^0.5
Print q_theo[0], q_theo[1], q_theo[2], q_theo[3] // just for debugging
End
In the main function O70LatPar(), you compute a wave "latind". In the function "fitting" you have used the name "latind" in the position of the independent variable wave.
In the fit function, the independent variable wave contains the X values corresponding to the Y values passed in the FuncFit command in the position in the command where you have q_expt. Since your FuncFit command has no /X flag, the independent variable (or X values) come from the wave scaling of q_expt. But you can associate a separate wave of X values using the /X flag:
FuncFit/N/Q/NTHR=0 fitting, latpar, q_expt/X=myXwave
The X wave must have the same number of points as the Y wave, so in this case, myXwave must have the same number of points as q_expt.
I feel like I haven't answered your question, though. Perhaps try again with some more details in your explanation.
John Weeks
WaveMetrics, Inc.
support@wavemetrics.com
January 27, 2012 at 09:06 am - Permalink
The wave "latind" is actually a matrix at the moment. It comprises 4 sets of h, k, and l. Think of it as vectors X0 through X3 (e.g., X0 = {h0, k0, l0}). So, I'm actually passing 12 points to "fitting", and "q_expt" has only 4 points.
Here's how I've approached the problem manually in Excel (I attached a screenshot):
I know what values of h, k, and l are allowed by nature. I make a (hopefully) good guess as to which observed peaks (i.e., values of q_expt) correspond to certain sets of h, k, and l. I then run a simple sum-of-squared errors analysis to calculate the values of a, b, and c. I then manually switch which observed q values go with which sets of h, k, and l and repeat the analysis. I'm attempting to automate this process in Igor.
Is there a direct analogue to Excel's solver functionality in Igor? My original intention was to write a simple function (sum of (q_theo - q_expt)^2) and use Optimize to find the minimum, but it appears you can't vary parameters this way.
Any additional input will of course be appreciated. At this point, I either need a way to send my h, k, l matrix to my current all-at-once fitting function, a way to automate Excel's solver functionality, or a way to split up the problem so I can use FuncFit.
January 27, 2012 at 02:06 pm - Permalink
But it sounds like you need to fit a solution for a, b, and c for each of several sets of h, k, l. So you need to do several fits, and you need to pass in values of hkl that will be treated as constants in any given fit.
The easiest way to pass in constants is to add them to the coefficient wave. So in your case, you would have a six-point coefficient wave with a, b, c, h, k, l. Since h, k, l are constants, you would pre-set them to the appropriate values and hold them during the fit.
A somewhat cleaner way to do it would be to use a structure fit function and pass the values of h, k, l as additional members of the structure. This eliminates the possibly error-prone requirement of holding the coefficients that correspond to h,k,l.
John Weeks
WaveMetrics, Inc.
support@wavemetrics.com
January 30, 2012 at 04:34 pm - Permalink