How to normalise two waves in a quicker way

hi all,

I have two sets of data. Each has two waves. The first one has X1, Y1 and the second has X2, Y2.

I'd like to normalise both Y1 and Y2 so that both will have the maximum point equal to 1, and other Y points will be scaled to the correct ratio accordingly.

I used to do this by just finding the maximun point and dividing the whole wave by its maximum to get a new wave. But if the wave has thousands of points, it here a quicker way of doing it?

cheers,

Wavemax(wave) returns the maximum value of the 'wave

Duplicate wave0, wave_nor
wave_nor=wave0/wavemax(wave0)

I usually use like this.
Jinhyung Kim wrote:

wave_nor=wave0/wavemax(wave0)


this will be fairly slow because WaveMax is evaluated for every point within the implicit loop for wave arithmetic. Better use something like:


Function normW(w)
    wave w
   
    variable ref = StartMStimer
   
    Duplicate/O w w_norm
   
    variable mx = wavemax(w)
    Multithread w_norm /= mx
   
    variable tme = stopMStimer(ref)
    printf "%g seconds \r", tme/1e6
end


If the thread opener tried this already, then I don't know a faster method!
You might try MatrixOP:

MatrixOP/O Y1norm = Y1/maxval(Y1)

MatrixOP has been highly optimized for speed. If you can do it with MatrixOP, it will almost always be faster, though with anything like this actual measurements are required to be sure of that.

And in Igor 7 where possible it will take advantage of multiple processors for even greater speed. Igor 7 is not yet in beta testing, though.

John Weeks
WaveMetrics, Inc.
support@wavemetrics.com
johnweeks wrote:
You might try MatrixOP:

MatrixOP/O Y1norm = Y1/maxval(Y1)

MatrixOP has been highly optimized for speed. If you can do it with MatrixOP, it will almost always be faster, though with anything like this actual measurements are required to be sure of that.

And in Igor 7 where possible it will take advantage of multiple processors for even greater speed. Igor 7 is not yet in beta testing, though.

John Weeks
WaveMetrics, Inc.
support@wavemetrics.com


Hello,

I was wondering how I can add a specific range in the X axis to calculate the maxval, for example from 0.2 to 0.5 seconds. I have done this with wavemax(Wave1, 0.2, 0.5) but doesn't work with matrixOP
Store your maximum value in a variable, then you can use either a matrixOP expression or a regular wave assignment statement. Like this:
make/n=100 junk = gnoise(10)        // a wave for testing filled with random gaussian noise
setscale/I x 0,1,junk           // Set the X scaling
Variable maxv = wavemax(junk, 0.2, 0.5) // find the maximum value within the specified X range
matrixOP junknorm = junk/maxv
--- or ---
junk /= maxv

MatrixOP here is convenient if you want the result in a second wave, because it automatically makes the wave "junknorm" for you. The simple wave assignment is easy to write if you want to overwrite your original data (which is usually not a good idea, but may be appropriate if it is some sort of intermediate result).

John Weeks
WaveMetrics, Inc.
support@wavemetrics.com
x2pnt and subrange would also work for you in Matrixop E.g.,
Variable p0 = x2pnt(wv,x0),p1=x2pnt(wv,x1)  //x0 and x1 set the desired x range in wv
Matrixop/o temp = subrange(wv,p0,p1,0,0) //temp now holds the data in subrange x0-x1
//now you can run matrix op commands in this (in fact, you could also nest this in the matrixop command you quoted)
matrixop/o result = temp/maxval(temp)
//then, finally, you would probably want to copy the x scaling from the original wave
setscale/p x,dimoffset(wv,0)+x0,dimdelta(wv,0),waveunits(wv,0),result
.
subrange works for rows and columns, there are other commands available to work with higher dimensions in matrixop.