How to use a function that returns a wave

How am I supposed to use a wave that is returned from a function?

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


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

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

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.

Well. The intermediate step is probably your answer.
"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

I've been reading that documentation all afternoon and getting myself tired up in circles.

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
//cumulative sum of a 1d wave
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.
Something like that?

Function/Wave DoTest()
    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
thomas_braun wrote:
Something like that?


No.

I'm doing something like this:
Function/Wave DoTest1()
    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.
Function CallMe()
    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.
how about

Function/Wave DoTest1()
    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
masheroz wrote:

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.



I think you want:

Make/O a = 1
Duplicate/O a, b
Integrate/meth=0 b
edit b
Yes! (re my functions)

No (re Integrate - I don't trust them to give me the correct result, as differentiate doesn't)
As Thomas suggested above, you should use MoveWave to move a free wave into the global space. This is more efficient than generating a new global wave using Make and copying the values from the free wave into the new global wave, though unless you're doing this on very large waves it probably won't matter from a practical standpoint.

#pragma rtGlobals=3     // Use modern global access method and strict wave access.
//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


masheroz wrote:

No (re Integrate - I don't trust them to give me the correct result, as differentiate doesn't)


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.
aclight wrote:
As Thomas suggested above, you should use MoveWave to move a free wave into the global space. This is more efficient than generating a new global wave using Make and copying the values from the free wave into the new global wave, though unless you're doing this on very large waves it probably won't matter from a practical standpoint.


I'll probably do this as it might make it less verbose.



aclight wrote:

masheroz wrote:

No (re Integrate - I don't trust them to give me the correct result, as differentiate doesn't)


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.


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 want