Define variable(s) for Funcfit
imksh2000
Each FF_* has variable x. Should I define FF_* as a variable or a wave?
Function Fitting_Engine(p,x)
wave p
variable x
nvar ci
nvar uc_occ_Y, uc_occ_Zr, uc_occ_O, ci, u_Y, u_Zr, u_O
wave ASF_Y, ASF_Zr, ASF_O, uc_position_Y, uc_position_Zr, uc_position_O
// ATOMIC POSITION //
// PERFECT UNIT CELL //
variable/c FF_uc, FF_uc_Y, FF_uc_Zr, FF_uc_O, FF_ctr
FF_uc_Y = atomic_frac_Y * ASF_Y * uc_occ_Zr * exp(ci*x*(temp_first_Y_position))*exp(-0.5*(x*u_Y)^2)
FF_uc_Zr = atomic_frac_Zr * ASF_Zr * uc_occ_Zr * exp(ci*x*(temp_first_Zr_position))*exp(-0.5*(x*u_Zr)^2)
FF_uc_O = 2*atomic_frac_O * ASF_O * uc_occ_O * exp(ci*x*(temp_first_O_position))*exp(-0.5*(x*u_O)^2)
FF_uc = FF_uc_Y + FF_uc_Zr + FF_uc_O
FF_ctr = 1 / (1-exp(-ci*x*c))
// DISTORTED UNIT CELLS //
variable i_F_duc
variable/c FF_duc_Y, FF_duc_Zr, FF_duc_O, FF_duc
wave duc_occ_O
FF_duc_Y = 0
FF_duc_Zr = 0
FF_duc_O = 0
for (i_F_duc=0;i_F_duc<numpnts(temp_duc_position_O_reset);i_F_duc+=1)
FF_duc_Y += atomic_frac_Y * ASF_Y* p[i_F_duc] * exp(ci*x*temp_duc_position_Y_reset[i_F_duc])*exp(-0.5*(x*u_Y)^2)
FF_duc_Zr += atomic_frac_Zr *ASF_Zr * p[i_F_duc] * exp(ci*x*temp_duc_position_Zr_reset[i_F_duc])*exp(-0.5*(x*u_Zr)^2)
FF_duc_O += 2*atomic_frac_O *ASF_O * duc_occ_O[i_F_duc] * exp(ci*x*temp_duc_position_O_reset[i_F_duc])*exp(-0.5*(x*u_O)^2)
endfor
FF_duc = FF_duc_Y + FF_duc_Zr + FF_duc_O
// INTERFACIAL MOLECULES //
variable/c FF_ads1, FF_ads2, FF_ads3, FF_ads
nvar d_spacing_water
FF_ads1 = ASF_Y*p[8]*exp(ci*x*(p[9]))*exp(-0.5*(x*p[10])^2)
FF_ads2 = ASF_Y*p[11]*exp(ci*x*(p[12]))*exp(-0.5*(x*p[13])^2)
FF_ads3 = ASF_Y*p[14]*exp(ci*x*(p[15]))*exp(-0.5*(x*p[16])^2)
FF_ads = FF_ads1 + FF_ads2 + FF_ads3
variable/c FF_adw1, FF_adw2, FF_adw, FF_lw
wave ASF_H2O
FF_adw1 = ASF_H2O * p[17] * exp(ci*x*(p[18]))*exp(-0.5*(x*p[19])^2)
FF_adw2 = ASF_H2O * p[20] * exp(ci*x*(p[21]))*exp(-0.5*(x*p[22])^2)
FF_adw = FF_adw1 + FF_adw2
FF_lw = (ASF_H2O * exp(ci*x*p[23]) * exp(-0.5*(x*p[24])^2)) / (1-exp(-0.5*(x*p[25])^2)*exp(ci*x*d_spacing_water))
// MAGNIFICATION FACTORS //
variable FF_mag, FT_Cell, FSpecular, FB
nvar cell_water_thickness, photon_wavelength, attenuation_length, r_e, suc_area
FT_cell = exp((-8*pi*cell_water_thickness)/(x*photon_wavelength*attenuation_length))
FB = (1-p[26])^2/(1+p[26]^2-2*p[26]*cos(x*c))
FSpecular = (4*pi*r_e/(x*suc_area))^2
FF_mag = p[27] * FB * FT_Cell * FSpecular
return FF_mag * magsqr(FF_uc*FF_ctr + FF_duc + FF_ads + FF_adw + FF_lw)
End
wave p
variable x
nvar ci
nvar uc_occ_Y, uc_occ_Zr, uc_occ_O, ci, u_Y, u_Zr, u_O
wave ASF_Y, ASF_Zr, ASF_O, uc_position_Y, uc_position_Zr, uc_position_O
// ATOMIC POSITION //
// PERFECT UNIT CELL //
variable/c FF_uc, FF_uc_Y, FF_uc_Zr, FF_uc_O, FF_ctr
FF_uc_Y = atomic_frac_Y * ASF_Y * uc_occ_Zr * exp(ci*x*(temp_first_Y_position))*exp(-0.5*(x*u_Y)^2)
FF_uc_Zr = atomic_frac_Zr * ASF_Zr * uc_occ_Zr * exp(ci*x*(temp_first_Zr_position))*exp(-0.5*(x*u_Zr)^2)
FF_uc_O = 2*atomic_frac_O * ASF_O * uc_occ_O * exp(ci*x*(temp_first_O_position))*exp(-0.5*(x*u_O)^2)
FF_uc = FF_uc_Y + FF_uc_Zr + FF_uc_O
FF_ctr = 1 / (1-exp(-ci*x*c))
// DISTORTED UNIT CELLS //
variable i_F_duc
variable/c FF_duc_Y, FF_duc_Zr, FF_duc_O, FF_duc
wave duc_occ_O
FF_duc_Y = 0
FF_duc_Zr = 0
FF_duc_O = 0
for (i_F_duc=0;i_F_duc<numpnts(temp_duc_position_O_reset);i_F_duc+=1)
FF_duc_Y += atomic_frac_Y * ASF_Y* p[i_F_duc] * exp(ci*x*temp_duc_position_Y_reset[i_F_duc])*exp(-0.5*(x*u_Y)^2)
FF_duc_Zr += atomic_frac_Zr *ASF_Zr * p[i_F_duc] * exp(ci*x*temp_duc_position_Zr_reset[i_F_duc])*exp(-0.5*(x*u_Zr)^2)
FF_duc_O += 2*atomic_frac_O *ASF_O * duc_occ_O[i_F_duc] * exp(ci*x*temp_duc_position_O_reset[i_F_duc])*exp(-0.5*(x*u_O)^2)
endfor
FF_duc = FF_duc_Y + FF_duc_Zr + FF_duc_O
// INTERFACIAL MOLECULES //
variable/c FF_ads1, FF_ads2, FF_ads3, FF_ads
nvar d_spacing_water
FF_ads1 = ASF_Y*p[8]*exp(ci*x*(p[9]))*exp(-0.5*(x*p[10])^2)
FF_ads2 = ASF_Y*p[11]*exp(ci*x*(p[12]))*exp(-0.5*(x*p[13])^2)
FF_ads3 = ASF_Y*p[14]*exp(ci*x*(p[15]))*exp(-0.5*(x*p[16])^2)
FF_ads = FF_ads1 + FF_ads2 + FF_ads3
variable/c FF_adw1, FF_adw2, FF_adw, FF_lw
wave ASF_H2O
FF_adw1 = ASF_H2O * p[17] * exp(ci*x*(p[18]))*exp(-0.5*(x*p[19])^2)
FF_adw2 = ASF_H2O * p[20] * exp(ci*x*(p[21]))*exp(-0.5*(x*p[22])^2)
FF_adw = FF_adw1 + FF_adw2
FF_lw = (ASF_H2O * exp(ci*x*p[23]) * exp(-0.5*(x*p[24])^2)) / (1-exp(-0.5*(x*p[25])^2)*exp(ci*x*d_spacing_water))
// MAGNIFICATION FACTORS //
variable FF_mag, FT_Cell, FSpecular, FB
nvar cell_water_thickness, photon_wavelength, attenuation_length, r_e, suc_area
FT_cell = exp((-8*pi*cell_water_thickness)/(x*photon_wavelength*attenuation_length))
FB = (1-p[26])^2/(1+p[26]^2-2*p[26]*cos(x*c))
FSpecular = (4*pi*r_e/(x*suc_area))^2
FF_mag = p[27] * FB * FT_Cell * FSpecular
return FF_mag * magsqr(FF_uc*FF_ctr + FF_duc + FF_ads + FF_adw + FF_lw)
End
Also, I cannot see where you are using certain values of p, for example p = 0 to 7. Why is this? And, with so many fitting coefficients, you might help make the code more readable by using a variable block at the start, for example as this ...
...
variable FF_mag_f = p[27]
Also, certain values that you define as globals via nvar would perhaps be better defined as static constants at the top of the procedure, for example ..
Static Constant uc_occ_Zr = ...
--
J. J. Weimer
Chemistry / Chemical & Materials Engineering, UAH
June 23, 2016 at 07:13 am - Permalink
Your code would not compile. For example:
Here the left hand side is a variable while on the right hand side you have ASF_O which is declared as a wave. You either need to have a wave expression, i.e., a wave on both sides of the expression or you need to use one point of the wave(s) on the right hand side. You need to address this issue before going any further.
Other comments:
If you are looking for efficiencies, consider removing every expression that does not depend on the fitting process and accessing it as either a constant or global. It may make your code less readable but it could pay off in execution time. For example, -8*pi*cell_water_thickness, photon_wavelength*attenuation_length and 4*pi*r_e/suc_area^2 do not appear to be evaluated in the fit so they should be computed outside and accessed as a single global. Similarly, d_spacing_water exists only as a product with ci so there is no reason to compute it each time.
Looking at your loop, you should probably replace numpnts(temp_duc_position_O_reset) with a variable evaluated once above the loop. Also, I don't see any declaration for the wave temp_duc_position_O_reset. Now depending on the size of NN=numpnts(temp_duc_position_O_reset) you could replace the loop with MatrixOP. I have a feeling though that NN is not large so in this case it is probably not worth the trouble.
I hope this helps,
A.G.
WaveMetrics, Inc.
June 23, 2016 at 10:59 am - Permalink
AG ... Quick question on this. Suppose I have to use a predefined wave in this way ...
Function SomeFitFunc(ww,pnt)
wave ww
variable pnt
wave wsin
return (ww[0]*wsin[pnt] + ww[1]*pnt) // this is just some dummy calculation to show the concept
end
IOW, suppose I want to use a wave that I am able to pre-define external to the fit function and want to reference as a "lookup" inside the fit function itself. What is the most effective way to do this?
--
J. J. Weimer
Chemistry / Chemical & Materials Engineering, UAH
June 28, 2016 at 01:34 pm - Permalink
Since you like complicated solutions... :)
Look into a Structure Fit Function (DisplayHelpTopic "Structure Fit Functions"). You can add a wave to the structure that gets passed to the fit function, which means you don't have to look it up inside the function. But it requires that you use a driver function to set up the structure and call FuncFit.
Otherwise, there is no way to get around the WAVE lookup. Use an all-at-once function to minimize the number of times the fit function gets called, and consequently, the number of times the wave has to be looked up. Make sure you have few (or no!) other waves in the current data folder.
Function SomeFitFunc(ww,p)
I hate to be pedantic, but it's really terrible to call an input variable "p". I know, it's almost as bad to call it "x", which we do numerous times in the documentation. We live and learn. And the OP had p for the coefficient wave. He will also learn this now :)
John Weeks
WaveMetrics, Inc.
support@wavemetrics.com
June 27, 2016 at 05:14 pm - Permalink
I'm just playing devil's advocate from the point where AG prompted the inquiry by his open-ended comment.
I appreciate the clarification if for no other reason than logging an easy reference point of the information in case anyone else has a similar question.
The insight is appreciated. That was my "quick and dirty" posting. Normally, I avoid such mistakes in my code.
--
J. J. Weimer
Chemistry / Chemical & Materials Engineering, UAH
June 28, 2016 at 11:10 am - Permalink
I know that; we've known you for a very long time! But I couldn't let it go in a public forum...
John Weeks
WaveMetrics, Inc.
support@wavemetrics.com
June 28, 2016 at 12:38 pm - Permalink
Thanks. I've edited the posted code to avoid mis-information.
--
J. J. Weimer
Chemistry / Chemical & Materials Engineering, UAH
June 28, 2016 at 01:34 pm - Permalink