LabVIEW Idea Exchange

cancel
Showing results for 
Search instead for 
Did you mean: 
Darin.K

Negative Values in Index Array or Array Subset

Status: New

There are many times when I need to grab the last element or last n elements of an array.   This usually involves a call to Array Size and then a subtraction, costing me time and block diagram clutter.  Array reversal is essentially free, but again costs clutter and clicks.  For common array types I have personal VIs to do the job, but that is just a band-aid with the proliferation of data types that I use.  My idea would be to treat negative values input to the index array or array subset VIs (for example) as counting from the end of the array.  The last value would have index -1 and so on.  To get the last n values I would put -n into the Array subset VI and that's it.   For expanding the Array Index VI, my preference would be that it counts down (-2,-3,-4,...).

 

 

 NegativeArrayIndex.png

33 Comments
gb119
Member

I'm not sure I totally buy the code breakage argument. The compiler knows when it is recompiling code saved as a previous version so it would be quite easy for it to set a 'use old style' flag on the primitive (with a glyph to indicate the backwards compaitble mode). New instances of the primitives could default to the new negative indices behvious (with an ini file flag to let old-fashioned folk drop the old-style primitives by default).

 

The 'off by one' problem where '0' is the first element from the state but '-1' is the first from the end is just a problem of how you think about an array. Think of it as a circular buffer with 0 pointing to an arbitary start point and positive and negative indices just become offsets from the start point. Of course you might want to stop offsets that go more than once aroudn the buffer from working (or perhaps not ?).

--
Gavin Burnell
Condensed Matter Physics Group, University of Leeds, UK
http://www.stoner.leeds.ac.uk/
Rob_Calhoun
Member

Since Index Array does not have an error output, the out-of-bounds behavior must be consistent.

 

I am with Altenbach: this change would break existing code and therefore I do not support it. We occasionally pass the output out of the Search Array function into Index Array, knowing we will get the default data type when the search fails.

 

-Rob 

Dragis
Active Participant

i like the idea, it works well for other languages, but at this point i don't see negative indexing being a practical extension to the labview language since it wasn't designed that way in the first place.

 

however, in every case i would have used this, i knew ahead of time whether i wanted to index from the end or not. therefore, i would be happy to settle for a right-click option on the node to configure it to index from the end of the array. the icon should change enough to make the configuration clearly visible on the diagram.

Yamaeda
Proven Zealot

I like the idea, although i'd break some of my own code since i use the -1 to get an empty array at times. 🙂 You could make your own index array which has a reverse array if index <0. A bit cumbersome as you'd need to make a polymorphic one for all existing arrays ... but still.

/Y

G# - Award winning reference based OOP for LV, for free! - Qestit VIPM GitHub

Qestit Systems
Certified-LabVIEW-Developer
AristosQueue (NI)
NI Employee (retired)

Have thought about this for a while...

 

Changing the existing Index Array function seems fraught with peril for existing code and doesn't seem to provide any sort of upgrade path. And I see the flaw in my suggestion of "just use Reverse Array" -- although that suggestion does work (and works without creating a copy of the array for those who don't know that), it doesn't allow for a programmatic computation that could give either a positive or negative value, which could be useful for things such as a circular buffer.

 

How about this:

Introducing a SECOND primitive that is "Index Array From Both Ends" or something like that does seem like a viable approach. Do you users think that would be too confusing for new users seeing both in the palettes? If we did this, what behavior would you expect for an unwired terminal? In the existing Index Array primitive, an unwired terminal is either index 0 (if it is the first terminal) or the previous index +1. Would it still be "previous +1" or would it be "previous +1 or -1 depending upon the sign of the previous"? Should the new primitive continue to return the last index if given an out of range value or would you introduce error out?

Darin.K
Trusted Enthusiast

Ah, baby steps.  Reverse Array was never really the answer.  It seems like a good idea, but one look at an actual implementation can be eye opening.  On top of that, the nice properties of Reverse Array are easily lost when you have to do it conditionally.  Put it inside a Case Structure and the compiler starts throwing copies around the BD.  (Maybe better in newer versions).  The 'better' workaround is a set of polymorphic VIs and the realization that a small number of datatypes go a long way.  XNodes are also feasible, but I would like to seem them distributable as packed project libraries.  You know, a single top level VI that gets dropped and a set of subVIs that aren't really useful outside the XNode.

 

While alternate indexing is on your mind, it is time to relax, forget about C++ and pointer math, clear your mind and only consider by value array representations.  Now ask yourself, why start from 0?  I think the FIRST element should be 1, beautiful symmetry with the last element being -1.  0 is a truly special, singular, special value for null or not found.  So many +1 and -1 nodes could be retired.  And everybody does the same comparison for not found (=0?) instead of (=-1? or <0?).

 

Enough pipe dreaming, as to the new primitive I would probably suggest a new style to handle the autoincrement/decrement.  I would allow the pulldown to create new groups or blocks of elements.  Only one index could be wired inside a block, the rest automatically increment or decrement depending on whether it is above or below the wired index.  I would allow multiple blocks to save space.  Pulling on the top or bottom of the node adds a new group, each group could have a divider which would add elements when pulled (pull down to add to the end of the upper group, pull up to add to the top of the group below) and remove elements when shift-pulled.  Not that this in any way, shape or form resembles an XNode of mine. 

AristosQueue (NI)
NI Employee (retired)

> Not that this in any way, shape or form resembles an XNode of mine. 

 

Have you posted it anywhere that others could evaluate it?

 

Regarding your tangent:

> I think the FIRST element should be 1,

 

I've worked in unit-indexed languages. I hope never again. I too thought it would be better in theory. The experience is miserable. You think +1 and -1 operations get retired. Instead, they move around and they add a few new ones.

 

And that's all I'll say on the topic since it really isn't ever going to happen in LV and I'd like to stay focused on the indexing problem at hand.

Intaris
Proven Zealot

Personally, I'm not sure a new primitive is the answer.  It almost sounds like we need a new datatype "Circular Buffer" which is an array on steroids.  Then you can introduce all kinds of relative operations and having a fixed length array to boot allows for all kinds of optimisations not possible with arrays......

 

But back on planet earth, I think either a second primitive or a right-click option on the index terminal of the array operator would both be workable.  Oh, and if a right.click would be implemented, it MUST be clear visibly which mode is selected!

GregSands
Active Participant

If we did this, what behavior would you expect for an unwired terminal? In the existing Index Array primitive, an unwired terminal is either index 0 (if it is the first terminal) or the previous index +1. Would it still be "previous +1" or would it be "previous +1 or -1 depending upon the sign of the previous"?

 

I'd like both! What about changing the default "box" at the index position to a + or - sign.  By default + is shown, but a right-click option could change that to -, and could be independent of the sign of the wired terminal.

 

Further, could one wire a middle index, and have + on one side, with - on the other?  Might get tricky with multiple wired terminals, but the earliest wiring would take precedence until another index is wired.

 

Should the new primitive continue to return the last index if given an out of range value or would you introduce error out?

 

I can see reasons for either of those (returning the first index for a negative out of range), but also for returning a "default" value (equivalent to the Case default), or even to wrap the index (modulo #elements), which makes it like a circular buffer.

johnsold
Knight of NI

Consider putting an "inversion circle" like the ones used in the Compound Arithmetic and some Boolean functions on the index input. Make it a right-click option. When the inverted mode is present the indexing is from the other end of the array (for that dimension only). 

 

This will allow indexing in either direction to be zero based and will not break legacy code.

 

Invert index.png

Lynn