Reference to a wave slice

Dear Igorians,

I am curious if one can create a reference to a slice of a wave, like so:
make/o/n=(10,2) w_source = gnoise(p)
wave w_slice = w_source[][1]


In C-speak, can one get a pointer to a specific address of the wave without copying data? And if not, what is the best way to go about something like this?

As far as I understand, using duplicate and/or make will deep copy the data and would lead, naturally, to independent changes in w_source and w_slice.
Have you looked at dependencies? They can be assigned using := perhaps they only work in the case of variables and not waves though.
sjr51 wrote:
Have you looked at dependencies? They can be assigned using := perhaps they only work in the case of variables and not waves though.


I am aware of the functionality dependencies provide. Dependencies, unfortunately, are not the answer to how one references a slice of a wave without duplicating memory.

best,
_sk
The nearest I can suggest is:
MatrixOP/FREE  w_slice = col(w_source,1)

though this has the cost of memory allocation.
Igor wrote:
The nearest I can suggest is:
MatrixOP/FREE  w_slice = col(w_source,1)

though this has the cost of memory allocation.


Would changes in w_slice propagate to w_source? Is the memory referenced or copied? But if there is allocation I would think it is copied...

Thanks.

best,
_sk
_sk wrote:
Would changes in w_slice propagate to w_source? Is the memory referenced or copied? But if there is allocation I would think it is copied...


It is copied. May I ask what your goal is?
thomas_braun wrote:
It is copied. May I ask what your goal is?


I have a 2d wave as output from an instrument (columns for channels) and was wondering if I can operate on various columns without copying/duplicating data everytime I need to operate on a particular column/channel. There is a side issue, namely, that each time when I operate on the copied column, I need to copy back the data to the 2d wave to "update". I can get around the issue by making a wave wave with each channel being a separate wave upon import in my analysis program and flattening to a 2d wave upon save for integrity with other functions already written expecting the instrument-output 2d wave. Which is the same as splitting the original 2d wave into channels and saving each wave in a datafolder; but somehow the wave/wave seems more compact.

As far as I understand, however, this pointer vs copy issue is a somewhat of a limitation in Igor. I don't quite get why Igor differentiates between a whole wave and a slice of a wave. The same way a wave header points to the beginning of the wave data it can also point to the beginning of the slice data. I don't remember off the top of my head, but there was also some checksumming going on, which can also be dealt wilth. A fat pointer scenario can also be conceived, in which case it is only the fat pointer that gets modified/ copied. I am just saying.

best,
_sk
_sk wrote:
thomas_braun wrote:
It is copied. May I ask what your goal is?


I have a 2d wave as output from an instrument (columns for channels) and was wondering if I can operate on various columns without copying/duplicating data everytime I need to operate on a particular column/channel. There is a side issue, namely, that each time when I operate on the copied column, I need to copy back the data to the 2d wave to "update". I can get around the issue by making a wave wave with each channel being a separate wave upon import in my analysis program and flattening to a 2d wave upon save for integrity with other functions already written expecting the instrument-output 2d wave. Which is the same as splitting the original 2d wave into channels and saving each wave in a datafolder; but somehow the wave/wave seems more compact.

As far as I understand, however, this pointer vs copy issue is a somewhat of a limitation in Igor. I don't quite get why Igor differentiates between a whole wave and a slice of a wave. The same way a wave header points to the beginning of the wave data it can also point to the beginning of the slice data. I don't remember off the top of my head, but there was also some checksumming going on, which can also be dealt wilth. A fat pointer scenario can also be conceived, in which case it is only the fat pointer that gets modified/ copied. I am just saying.

best,
_sk


Igor partialy suports a wave reference poiting to the midle of a wave,see:
make/N=(100,100) aaa=x*y
display aaa[][30]

However,this is not a general feature!
Wish Igor can realize this feature in the future. It is really convinient when operating on 2D waves if one can reference to the midle of the wave.
@Wings: Not really. This is the subrage syntax. Here you can USE slices but not reference to them.

@_sk: The pointer would only work along rows and has be limited to "well-behaved" operations. Imagine to insert data points in a slice along layers...

A useful thing -- for lazy guys like myself -- might be aliases for subranges (SubRangeAlias) on a parser level:
Wave w_keithley
SRA Ch5=w_keithley[][5]
ch5+=10

where 'Ch5' is automatically replaced by 'w_keithley[][5]' and then compiled. This is not a pointer to that part of the wave. As a benefit, it would also work with fancy ranges, e.g., '[p][p]' (sic).
It might also be handy in the scope of the command window in case one uses data with long names stored in different data folders at the same time.

HJ
_sk wrote:

I have a 2d wave as output from an instrument (columns for channels) and was wondering if I can operate on various columns without copying/duplicating data everytime I need to operate on a particular column/channel. There is a side issue, namely, that each time when I operate on the copied column, I need to copy back the data to the 2d wave to "update". I can get around the issue by making a wave wave with each channel being a separate wave upon import in my analysis program and flattening to a 2d wave upon save for integrity with other functions already written expecting the instrument-output 2d wave. Which is the same as splitting the original 2d wave into channels and saving each wave in a datafolder; but somehow the wave/wave seems more compact.

As far as I understand, however, this pointer vs copy issue is a somewhat of a limitation in Igor. I don't quite get why Igor differentiates between a whole wave and a slice of a wave. The same way a wave header points to the beginning of the wave data it can also point to the beginning of the slice data. I don't remember off the top of my head, but there was also some checksumming going on, which can also be dealt wilth. A fat pointer scenario can also be conceived, in which case it is only the fat pointer that gets modified/ copied. I am just saying.

best,
_sk


You're correct that there's no concept of a wave reference that's a "slice" or some portion of a real wave. A few operations accept a subrange, specified either with /R or /RMD flags, or by a regular subrange specification like wave0[0,10][*]. We've considered the idea of adding something like a virtual slice, but doing so would be a *lot* of work. The code for pretty much every operation and function that acts on waves would need to be modified substantially.

If you're using Igor 7, be sure to check out SplitWave, which will make splitting the 2D wave into multiple 1D waves fairly quick and easy. I'd recommend using the /OREF flag so you have wave references to the 1D output waves. Then you can do your analysis on the 1D waves and then use Concatenate to combine the 1D waves back to a 2D wave. Unfortunately Concatenate still doesn't have a mode that takes a wave reference wave as the input, so unless the # of columns you'll be concatenating is fixed, you'll want to use the S_waveNames output of SplitWaves as the input to Concatenate.
ImageTransform putCol/putRow is a fast way to update a slice of a wave, instead of using [p] and [q] indices. If you want to update all slices Concatenate might be faster, though.
_sk wrote:
I have a 2d wave as output from an instrument (columns for channels) and was wondering if I can operate on various columns without copying/duplicating data everytime I need to operate on a particular column/channel. There is a side issue, namely, that each time when I operate on the copied column, I need to copy back the data to the 2d wave to "update".

Depending on the complexity of the operation, you may be able to write a helper function that takes care of the copying bits. Here's a not-very-polished and possibly slow example that uses a few of the operations previously mentioned in this thread:
function OperateOnSlice(w_source,q,operation)
    wave w_source
    variable q
    string operation
    MatrixOP/O w_slice=col(w_source,q)
    operation = "w_slice=w_slice"+operation  //Adapt to the application
    Execute operation
    ImageTransform/G=(q)/D=w_slice putCol w_source
    KillWaves w_slice
end

function testSliceOperation()
    make/o/n=(10,2) w_source=gnoise(p)
    OperateOnSlice(w_source,1,"+100")
end
Thanks to all for taking the time to reply. I will surely make use of all the pointers provided in the thread.

best,
_sk