When is a (1 column) wave not a (1D) wave?

I have some code that creates a one-column, as opposed to one-dimensional, text wave. Redimension /N=(42,1) foo is not the same as Redimension /N=(42) foo. As far as I can make out, I did this so that I could add a dimension label for the column (which can be used as a column label in a listbox). The code stopped working, and I tracked down the problem to wave referencing: changing foo[24] to foo[24][0] fixed the problem.

I checked this from the command line: print foo[24] gave an indexing error, print foo[24][0] is allowed. foo[24] gives an empty string rather than an indexing error in a function.

Out of curiosity I closed the edited procedure file and opened the original that referenced the single column wave with just a row number, and magically it works again. Now, from the command line I can execute print foo[24] and the contents of the foo[24][0] is printed. In both cases dimsize(foo,1) returns 1.

Does this mean that Igor is inconsistently fussy about indexing of 2D waves, allowing me to get away with bad code, or is there something that I'm missing that could be different about these waves? I've simplified the code a bit in the description above, in particular the one-column text wave is overwritten by duplicating the output from ListToTextWave, followed by redimensioning to one column, so it's conceivable that something else is causing the seemingly inconsistent behaviour.

Can anyone shed some light on this?

System Information:
IGORVERS:8.03
BUILD:32517
IGORKIND:pro64

OS:Macintosh OS X
OSVERSION:10.13.6
LOCALE:US
IGORFILEVERSION:8.03B01

This is perhaps peripherally related to another question that I posted a while ago:

https://www.wavemetrics.com/forum/general/why-do-wave-assignments-zero-…

tony

 

 

 

 

This question also has relevance to the results produced by MatrixOP; For example, from the Help file, see the last line below

MatrixOp and Wave Dimensions
MatrixOp was designed to optimize operations on 2D arrays (matrices) but it also supports
other wave dimensions in various expressions. However it does not support zero point waves.
A 1D wave is treated as a matrix with one column.

I have found that treating a MatrixOP 1D wave vs a "normal" 1D wave depends on what you are doing. To be safe, it is best not to ignore the second index, even if pretending the wave is pure 1D may sometimes work.

As far as MatrixOP is concerned:

every 1D wave is by definition a 2D wave of a single column.  I do not believe that MatrixOP is particularly fussy about this and in fact, in IP9 this notion will, per user requests, is extended so that a 2D wave can, under some circumstances be treated as a one-layer 3D wave, etc.

As far as I can see, that 1D wave can now be a special case of a 4D wave which may be OK* in MatrixOP but not when you try to use wave indexing as in wave[p][q][r].

*This extension will not be implemented for certain MatrixOP functions that have prescribed behavior for dimensions other than 2. 

 

In reply to by Igor

Thanks for the responses.

Clearly failing to index the column is a coding error. I was just surprised that most of the time the incorrect reference doesn't give an error. That makes debugging hard for a lax programmer like me.

It's weird that the same code typed on the command line seems sometimes to result in an indexing error and other times not. What I'm seeing is something like this:

make /n=(128,1) foo=x // create a one-column wave
print foo[2] // sometimes prints foo[2][0]

There's no reason that I need to create one-column waves, so it doesn't really cause any problems. The zero length wave assignments thing is more of an annoyance.

 

The explanation of all this, of course, involves internal data structures. Internally, we keep an array of dimension sizes (int64_t nDim[4]) and the difference between a 1D wave and a 1-column matrix is that nDim[1] is zero or one. Mathematically, of course, these are equivalent, but from a coding point of view it can require special-case code to allow a 1-column wave to behave like a 1D wave. We haven't found all those places that require a special case, and there may be some where it could have a negative performance impact to add the necessary conditionals. The fact that it may require special-case code means that some parts of Igor have it and others don't- Igor is a big program!