How to use a function that returns a wave
masheroz
I'm setting up some general functions to operate on some waves to generate other waves. As such, I don't care about the intermediate results, just the final answer.
I have the following functions:
//cumulative sum of a 1d wave
function/WAVE cumsum(w)
wave w
make/o/n=(numpnts(w))/FREE cs
cs[0] = w[0]
variable i
for(i=1;i<numpnts(cs); i+=1)
cs[i] = w[i] + cs[i-1]
endfor
return cs
end
//add the first value of a wave to each other value
function/WAVE wplushalf(w)
wave w
make/O/FREE/N=(numpnts(w)) wph
wph = 0.5*(w + w[0])
return wph
end
function doit(w)
wave w
wave A = cumsum(w) - wplushalf(w) //not showing in my data browser and is equal to cs, not cs-wph
print A
end
function/WAVE cumsum(w)
wave w
make/o/n=(numpnts(w))/FREE cs
cs[0] = w[0]
variable i
for(i=1;i<numpnts(cs); i+=1)
cs[i] = w[i] + cs[i-1]
endfor
return cs
end
//add the first value of a wave to each other value
function/WAVE wplushalf(w)
wave w
make/O/FREE/N=(numpnts(w)) wph
wph = 0.5*(w + w[0])
return wph
end
function doit(w)
wave w
wave A = cumsum(w) - wplushalf(w) //not showing in my data browser and is equal to cs, not cs-wph
print A
end
But wave A doesn't appear in my data browser, and it is equal to cumsum, not cumsum-wplushalf
If I change my last function to
function doit(w)
wave w
make/O/N=(numpnts(w)) A
A = cumsum(w) - wplushalf(w) //not showing in my data browser and is equal to cs, not cs-wph
end
wave w
make/O/N=(numpnts(w)) A
A = cumsum(w) - wplushalf(w) //not showing in my data browser and is equal to cs, not cs-wph
end
I get an ambiguous wavepoint number error referring to cumsum(w)
If I try and use
function doit(w)
wave w
make/O/N=(numpnts(w)) A, d1, d2
wave d1=cumsum(w)
wave d2=wplushalf(w)
A = d1-d2
end
wave w
make/O/N=(numpnts(w)) A, d1, d2
wave d1=cumsum(w)
wave d2=wplushalf(w)
A = d1-d2
end
I get an "expected assignment operator" error pointing to wplushalf(w), skipping cumsum(w)! If I remove the "wave" text before d1 and d2, I get back to my ambiguous wavenumber error.
The examples that I've found in the manual with regards to returning waves around only seem to deal with the first time you use the function, not the second, as I'm trying to do.
"cumsum()" creates a free wave "cs" and returns NOT the wave itself, but a reference to that wave. However, it is deleted once the function is finished. So you return an expired pointer.
The same in the other function. Finally, you try to subtract wave references from each other (I only know pathological cases in which this might make sense).
I recommend to read the manual concerning the FREE and WAVE flags and things will be clear. Maybe also have a look on the "sum"-function.
HJ
September 23, 2015 at 02:59 am - Permalink
I don't understand how I am supposed to use a function to return a wave without a whole load of waves cluttering up my data browser. Isn't that the entire point of free waves?
I've tried with and without the /WAVE modifier and with/without the /FREE modifier, and I can't figure it out.
.
I've managed to force it to work by doing
function cumsum(w)
wave w
make/o/n=(numpnts(w)) cs
cs[0] = w[0]
variable i
for(i=1;i<numpnts(cs); i+=1)
cs[i] = w[i] + cs[i-1]
endfor
return cs
end
//add the first value of a wave to each other value
function wplushalf(w)
wave w
make/O/N=(numpnts(w)) wph
wph = 0.5*(w + w[0])
return wph
end
function doit(w)
wave w
make/O/N=(numpnts(w)) A
cumsum(w)
wplushalf(w)
wave cs, wph
A = cs - wph //cumsum(w)-wplushalf(w)
print A
end
but that doesn't do anything to make programming easier. I still need to know that name of the wave each of my functions creates, I need to explicitly clean up after them, I can't assign the output of one of the functions directly to another wave. It's enough to drive a man to drink, or at least Python, or Matlab.
.
Also, the SUM function doesn't do what I want it to do. It returns a single number, I want a wave the same dimension as what I give it, with each value in the output being the sum of the elements up until that point in the originainal wave.
September 23, 2015 at 07:03 am - Permalink
Make/FREE data = p
return data // returning free wave
End
Function CallMe()
Wave data = DoTest() // wave reference to free wave
print data
return NaN // no more references to the wave "data", data will be deleted
End
September 23, 2015 at 06:55 am - Permalink
No.
I'm doing something like this:
Make/FREE data = p
return data // returning free wave
End
Function/Wave DoTest2()
Make/FREE data = 2*p
return data // returning free wave
End
Function CallMe()
Wave theAnswer = DoTest1() + DoTest2()
print theAnswer
End
theAnswer only reflects the values in DoTest1(), nothing is done about the addition.
I want theAnswer to exist in my data browser to use in other things.
September 23, 2015 at 07:23 am - Permalink
WAVE a = DoTest2()
WAVE b = DoTest1()
a += b
print a
End
For making a non-free wave from free waves have a look at
MoveWave
.September 23, 2015 at 08:04 am - Permalink
Make/FREE data = 1
return data // returning free wave
End
Function/Wave DoTest2()
Make/FREE data = 2
return data // returning free wave
End
Function CallMe()
Wave a = DoTest1()
wave b = DoTest2()
Make/O /N=(numpnts(a)) theAnswer = 0
theAnswer = a+b
return 1
End
September 23, 2015 at 08:22 am - Permalink
I think you want:
Duplicate/O a, b
Integrate/meth=0 b
edit b
September 23, 2015 at 08:45 am - Permalink
No (re Integrate - I don't trust them to give me the correct result, as differentiate doesn't)
September 23, 2015 at 07:43 pm - Permalink
//cumulative sum of a 1d wave
function/WAVE cumsum(w)
wave w
make/o/n=(numpnts(w))/FREE cs
cs[0] = w[0]
variable i
for(i=1;i<numpnts(cs); i+=1)
cs[i] = w[i] + cs[i-1]
endfor
return cs
end
Function/WAVE cumsum2(w)
wave w
Duplicate/O/FREE w, b
Integrate/meth=0 b
return b
End
//add the first value of a wave to each other value
function/WAVE wplushalf(w)
wave w
make/O/FREE/N=(numpnts(w)) wph
wph = 0.5*(w + w[0])
return wph
end
function doit(w)
wave w
wave A = cumsum(w)
WAVE A1 = cumsum2(w)
print A
print A1
Wave B = wplushalf(w)
a -= b
KillWaves/Z root:doitOutput // Must kill existing wave as MoveWave has no /O for overwrite flag.
MoveWave a, root:doitOutput
end
It's not nice to slander Igor without at least explaining why you think differentiate doesn't give the correct result (and under what conditions). If you've actually discovered a bug, we'd like to know about it so that we can fix it. If you wish, you can contact support@wavemetrics.com directly. If you do, please provide detailed instructions we can use to reproduce what you've found (including any Igor experiment files that are necessary), the version of Igor and your OS and version, and you Igor Pro serial number.
As the test above points out, your cumsum() function and my cumsum2() function, which uses Integrate like ChrLie suggested, return the same values.
September 24, 2015 at 06:25 am - Permalink
I'll probably do this as it might make it less verbose.
I was battering my head trying to do make my GUI work to present my logic, and I didn't properly explore Differentiate.
Differentiate/METH=1/EP=1 tmp/D=tmp_DIF
does what I wantSeptember 24, 2015 at 06:50 pm - Permalink