Merge 2 waves
MG
I want to merge multiple 3D waves in a way, that the layers from the different waves are alternating. Thus giving MergeWave[][][0] = a[][][0], MergeWave[][]1] = b[][][0], MergeWave[][][2] = a[][][1], MergeWave[][]3] = b[][][1] and so on...
Currently I'm looping over all layers of MergeWave, but this scales rather badly with the size of the input waves. Is there a better way?
Function merge()
Make /O /N=(500,500, 100) a = 0
Make /O /N=(500, 500, 100) b = 1
Make /O /N=(500, 500, 200) MergeWave
Variable i, timerRefNum, microSeconds
timerRefNum = startMSTimer
for (i=0; i<50; i+=1)
MergeWave[][][i*2] = a[x][y][i*2]
MergeWave[][][i*2+1] = b[x][y][i*2+1]
endfor
microSeconds = stopMSTimer(timerRefNum)
Print microSeconds/1000, "ms passed."
End
Make /O /N=(500,500, 100) a = 0
Make /O /N=(500, 500, 100) b = 1
Make /O /N=(500, 500, 200) MergeWave
Variable i, timerRefNum, microSeconds
timerRefNum = startMSTimer
for (i=0; i<50; i+=1)
MergeWave[][][i*2] = a[x][y][i*2]
MergeWave[][][i*2+1] = b[x][y][i*2+1]
endfor
microSeconds = stopMSTimer(timerRefNum)
Print microSeconds/1000, "ms passed."
End
Make /O /N=(500,500, 100) a = 0
Make /O /N=(500, 500, 100) b = 1
Make /O /N=(500, 500, 200) MergeWave, MergeWave_New
Variable i, timerRefNum, microSeconds
timerRefNum = startMSTimer
for (i=0; i<50; i+=1)
MergeWave[][][i*2] = a[x][y][i*2]
MergeWave[][][i*2+1] = b[x][y][i*2+1]
endfor
microSeconds = stopMSTimer(timerRefNum) / 1e6
variable myTime
timerRefNum = startMSTimer
Make /N=(DimSize(a, 2)) /FREE W_Dummy // this is just a trick to use the MultiThread keyword
MultiThread W_Dummy = MergePlane(a, b, MergeWave_New, p)
myTime = StopMSTimer(timerRefNum) / 1e6
Printf "Original: %g. Now: %g\r", microSeconds, myTime
End
ThreadSafe Function MergePlane(M_PlaneFromThisWave1, M_PlaneFromThisWave2, M_PlaneToThisWave, fromIndex)
wave M_PlaneFromThisWave1, M_PlaneFromThisWave2, M_PlaneToThisWave
variable fromIndex
ImageTransform /P=(fromIndex) getPlane, M_PlaneFromThisWave1
wave M_ImagePlane
ImageTransform /D=M_ImagePlane /P=(2 * fromIndex) setPlane, M_PlaneToThisWave
ImageTransform /P=(fromIndex) getPlane, M_PlaneFromThisWave2
wave M_ImagePlane
ImageTransform /D=M_ImagePlane /P=(2 * fromIndex + 1) setPlane, M_PlaneToThisWave
End
Result on my laptop:
About 50 times faster.
June 6, 2013 at 05:42 am - Permalink
Make /O /N=(500,500, 100) a = 0
Make /O /N=(500, 500, 100) b = 1
Make /O /N=(500, 500, 200) MergeWave
Variable timerref
timerref = StartMSTimer
Multithread MergeWave[][][0,;2] = a[p][q][r/2]
Multithread MergeWave[][][1,;2] = b[p][q][floor(r/2)]
Variable microSeconds = stopMSTimer(timerref)
Print microSeconds/1000, "ms passed."
end
On my 8-core Mac Pro:
959.949 ms passed.
Running 741's version:
Original: 3.95354. Now: 0.0563738
So ImageTransform wins, hands down.
Some comments on your code...
a[x][y][i*2]
On the right side of a wave assignment, square brackets refer to point numbers (rows, columns, etc.) but x and y refer to the *scaled* values from the left side. Your code works because you didn't set wave scaling on your waves, so the scaled and unscaled values are the same. The code will fail if you ever feed it a wave with scaling.
a[x][y][i*2]
b[x][y][i*2+1]
I think you want just [i] in both cases, and run the loop for 100 iterations:
for (i=0; i<100; i+=1)
John Weeks
WaveMetrics, Inc.
support@wavemetrics.com
June 6, 2013 at 08:53 am - Permalink