Function returning wave value of zero with variable in SetFormula
My end goal is to create a Gaussian kernel plot, as well as a cumulative density graph of the kernel plot. The first step is to create Gaussian curves using the “gauss” command. Each curve’s mean is to be defined by indexing the values of the wave “i_distr.” All curves will have the same standard deviation, defined by the variable “width.”
My user-defined function will sum each Gaussian curve via a for loop, overwriting “g” with each successive indexing of “i_distr.” Within the for loop, “g” will be summed to “gsum,” thus creating the kernel plot to display the total contributions from each individual Gaussian curve. “gsum_int” is also introduced at the end to create a graph of the cumulative density.
The function works fine when I use integer values for the “gauss” command’s mean and width. However, when either of these values is substituted for the “i_distr” indexing or “width” variable (representing mean and width, respectively), both “gsum” and “gsum_int” waves contain only 0.
This is how my function is written when it works (i.e., with integers in the “gauss” command, the wave values are non-zero; I've used 8 as an example integer for both the index and the width here):
wave i_distr
variable index
variable width
width=5
make /n=(WaveMax(i_distr)+10) /d gsum
for(index=0; index<dimsize(i_distr,0); index+=1)
make /n=(WaveMax(i_distr)+10) /d /o g
SetFormula g, "gauss(p,i_distr[8],8)"
gsum+=g
endfor
display gsum
duplicate gsum gsum_int
integrate gsum_int
display gsum_int
End
This is how I’d like my function to be written, but which spits out waves of zero values for "gsum" and "gsum_int" if the function is written like this (I hope to include indexing “i_distr” and the “width” variable):
wave i_distr
variable index
variable width
width=5
make /n=(WaveMax(i_distr)+10) /d gsum
for(index=0; index<dimsize(i_distr,0); index+=1)
make /n=(WaveMax(i_distr)+10) /d /o g
SetFormula g, "gauss(p,i_distr[index],width)"
gsum+=g
endfor
display gsum
duplicate gsum gsum_int
integrate gsum_int
display gsum_int
End
Thank you in advance for your help!
SetFormula should be rarely used. The formula is evaluated periodically and not when a function is running. Also, you can't use local variables such as width in a formula. Local variables cease to exist when the function ends and so will not exist when Igor evaluates the formula. Also formulas create a web of dependencies that become hard to keep track of.
Here is a rewrite of your function. I have no way to test it.
Wave i_distr
Variable i_distro_num_rows = DimSize(i_distr,0)
Variable index
Variable width = 5
Variable numPoints = WaveMax(i_distr)+10
Make/N=(numPoints) /D gsum
for(index=0; index<i_distro_num_rows; index+=1)
gsum += gauss(p,i_distr[index],width)
endfor
Display gsum
Duplicate gsum gsum_int
Integrate gsum_int
Display gsum_int
End
Note that I also used local variables to avoid calculating the same quantity (e.g., WaveMax(i_distr)+10)) each time through the loop. Besides saving time, the use of a local variable makes the code more readable if you use a descriptive name for the local variable.
September 27, 2018 at 09:38 am - Permalink
In reply to SetFormula should be rarely… by hrodstein
It worked! Thank you for the advice on local variables; I'm a fairly new user and it helps to understand.
September 27, 2018 at 12:28 pm - Permalink