# Average Waves question Hi,

I have an experiment with several XY pairs that I would like to average. The X data is variable (∆) between waves, but runs from -20ish to 120ish. All have a common point at 0. I would like to use the Average Waves package to generate an average wave trace with scaling such that it has a point at 0 (for curve fitting purposes). Right now, the scaling of the average means the interpolation does not happen at 0. My question is:

How does the panel decide what scaling and how many points to use for the average, and can this be changed?

If I knew how the scaling worked I could create two extra XY pairs for each wave at the beginning and end of the waves at constant X such that the average wave placed a point at 0. Hopefully this makes sense.

Any help would be very much appreciated.
Average Waves just takes a bunch of waves and averages them down to one wave. It does it row-wise; it takes each of the row 0 points, averages them and uses the average as the row 0 point in the new wave. It doesn't actually care about X scaling.

It sounds to me like what you want to do is just beyond the scope of Average Waves. You probably need to write a special-purpose function to do the job.

John Weeks
WaveMetrics, Inc.
support@wavemetrics.com
Thank you for your reply. The Average Waves panel does do the averaging row by row when the X scaling is constant. But it doesn't do it like this when the X scaling between waves is variable. For example, I have 11 XY wave pairs with ~54 points each. Average waves generates an average wave with 216 points and constant ∆. I assumed that it somehow decides the density of points and then averages at each ∆X using interpolation of the original waves to find the level at that value of X to then generate the average value.

My solution for now is to check the number of points for the average wave (say 216).
Make a new XY pair with {-20, -10, 0, 10, 195} and {1, nan, 0, nan, 1}. My real data start at >-20 and finish at <+120.
Make the average again. It still generates 216 points, but now ∆=1 so that it puts a point at 0.
sjr51 wrote:
Thank you for your reply. The Average Waves panel does do the averaging row by row when the X scaling is constant. But it doesn't do it like this when the X scaling between waves is variable.

That's because scaling is irrelevant if they all have the same scaling.

Since you have waves with different scaling, I would write a script to do the following.

1. Determine common x-range of all waves provided (data points outside this range can't really be averaged). Ignore step 1 if all waves have same outer limits for x.
2. Create waves for results (XY)
3. use the interp function to interpolate the value from each data wave at the desired output x-value
4. Average these interpolated values
5. Repeat 2-4 for each X value in range.
Well, what do you know- when I first wrote WavesAverage.ipf Jim Prouty enhanced it to pay attention to X scaling and to do interpolation for mismatched X values. A brief scan of the code didn't really enlighten me as to the method it uses for picking the X values for output, though. Maybe Jim can tell us.

John Weeks
WaveMetrics, Inc.
support@wavemetrics.com
johnweeks wrote:
Well, what do you know- when I first wrote WavesAverage.ipf Jim Prouty enhanced it to pay attention to X scaling and to do interpolation for mismatched X values. A brief scan of the code didn't really enlighten me as to the method it uses for picking the X values for output, though. Maybe Jim can tell us.

fWaveAverage() has a non-point-for-point mode that kicks in with mismatched waves such as you describe.

The X values generated are interpolated X values to encompass the min x to max x range (computed over all the waves). The number of points in the result is increased to compensate for this interpolation (with safeguarding against too many points):
else
// can't do point-for-point because of different point range or scaling or there are multiple X waves
Variable firstAvePoint,lastAvePoint,point,xVal,yVal

Variable newLength= 1 + round(abs(maxXmax - minXmin) / minDeltaX)
maxLength= min(maxLength*4,newLength)   // avoid the case where one very small deltaX in an XY pair causes a huge wave to be created.

Make/N=(maxLength)/D/O \$AveName
Wave/Z AveW=\$AveName
AveW= 0
Wave w=\$StringFromList(0,ListOfWaves)
CopyScales w, AveW // just to get the data and x units
SetScale/I x, minXmin, maxXmax, AveW    // set X scaling to all-encompassing range

Make/O/N=(maxLength)/FREE TempNWave= 0

Then each wave's contribution is computed by Y interpolation and summed into AveW while keeping track of the number of waves contributing to the sum at each point in TempNWave:

for (i = 0; i < numWaves; i += 1)
thisXMin= xRange[i]
thisXMax= xRange[i]
if( thisXMin > thisXMax )   // swapped X range (X values decrease with increasing point number)
tmp= thisXMin
thisXMin= thisXMax
thisXMax= tmp
endif
firstAvePoint= ceil(x2pnt(AveW,thisXMin))   // truncate the partial point numbers...
lastAvePoint= floor(x2pnt(AveW,thisXMax))   // ... by indenting slightly
WAVE wy=\$StringFromList(i,ListOfWaves)
Wave/Z wx= \$StringFromList(i,ListOfXWaves)
for (point = firstAvePoint; point <= lastAvePoint; point += 1)
xVal= pnt2x(AveW, point)
if( WaveExists(wx) )
yVal= interp(xVal, wx, wy)
else
yVal= wy(xVal)
endif
if (numtype(yVal) == 0)
AveW[point] += yVal
TempNWave[point] += 1
endif
endfor
endfor

--Jim Prouty
Software Engineer, WaveMetrics, Inc.