Jump to content

New Array VI


Recommended Posts

More submissions to OpenG. This time I have a few array functions that I have had to use over the years. These VIs are for taking a 1D array and turning it into a 2D array, taking a 2D array and turning it into a 1D array, and to simply get the last element of at 1D array.

Thoughts? Critisism? Praise? Ideas to make it better? Good for OpenG?

1D to 2D array.llb

2D to 1D array.llb

Final Array Element.llb

  • Like 1
Link to comment

The method I always used to get the last element in an array is the "Delete Element From Array". If you don't wire anything to the index, or length, you get a scalar of the last element in the array as the "Deleted Portion".

This is actually mentioned in the help so I wouldn't expect this functionality to change.

Edited by hooovahh
  • Like 2
Link to comment

The method I always used to get the last element in an array is the "Delete Element From Array". If you don't wire anything to the index, or length, you get a scalar of the last element in the array as the "Deleted Portion".

As you mention, it is in the online help for the function. We also try to indicate this behavior in the Context Help for Delete From Array:

post-4441-0-58210100-1349719267.png

The fact that "last elem" is in parenthesis indicates that this is the behavior when you leave the index input unwired. If this isn't discoverable enough (which I'm thinking may be the case if people are writing VIs to do it), then how could we make it more obvious? I use this behavior of Delete From Array all the time...in fact, I may use Delete From Array just to get the last element of a 1D array more than I use it to delete stuff... :P

Link to comment

I use this behavior of Delete From Array all the time...in fact, I may use Delete From Array just to get the last element of a 1D array more than I use it to delete stuff... :P

I get a little twitch every time I branch an array wire, I have convinced myself that the compiler is clever enough to know that branching into an Index Array will not modify the array so inplaceness will survive. In most cases LV is also good at ignoring the code related to unwired outputs in the primitives, but I would be (pleasantly) surprised if the compiler recognized that branching an array into a Delete primitive to simply get the last element was also inplace.

Link to comment

As you mention, it is in the online help for the function. We also try to indicate this behavior in the Context Help for Delete From Array:

post-4441-0-58210100-1349719267.png

The fact that "last elem" is in parenthesis indicates that this is the behavior when you leave the index input unwired.

Okay this bugs me a little (but I do use this feature). What I normally see is the control name shown, and then in parenthesis I see the default value, if the value is not the default for that data type. So I may have a VI that will show or hide a VI, and I would want it to show by default. So I would have the control named "Show UI?" and the default would be made TRUE, which is what I would put in parenthesis. So my help would show "Show UI? (TRUE)". But this logic does not stand up with this VI, because I see "index 0 (last element)" is the control named "index 0"? No, it is index and the default is "last element" so I would want to see "index (last element)". I don't believe this is any real standard it is just what I've seen.

But now that I've thought about it I believe this is probably a lesser known feature, because it is not consistent with the other Array functions. If I leave an Index Array unwired it grabs the first element, not the last. I understand a VI can differ with functionality from one to another, I just think this is one reason why someone would not think that this VI works in this way.

Also add to the fact that not many VIs (only primitives I believe) behave differently if nothing is wired, verses the constant made from that terminal. I cannot make a sub VI that has a default of a blank string as a terminal input, but have the VI behave differently if I wire a blank string to it, versus wiring nothing to it. Again it goes to the inconsistency seen between this primitive, and other VIs that developers are familiar with.

Link to comment
I get a little twitch every time I branch an array wire, I have convinced myself that the compiler is clever enough to know that branching into an Index Array will not modify the array so inplaceness will survive. In most cases LV is also good at ignoring the code related to unwired outputs in the primitives, but I would be (pleasantly) surprised if the compiler recognized that branching an array into a Delete primitive to simply get the last element was also inplace.

The help mentions subarray for both outputs. A very important distinction to many of the array primitives if you're worrying about memory. I think what LabVIEW really needs is a good discussion in the help about what a subarray actually is with proper links from the primitives that can actually create subarrays.

For the uninitiated, subarrays don't require new allocations of the actual array data as long as you don't go modifying the data in either the subarray or original array wires. Subarrays are indeed key to how many of the array primitives operate so efficiently-- basically they point to the same data as the original array, albeit have different scalars keeping track of each dimension in the array.

  • Like 1
Link to comment

The help mentions subarray for both outputs. A very important distinction to many of the array primitives if you're worrying about memory. I think what LabVIEW really needs is a good discussion in the help about what a subarray actually is with proper links from the primitives that can actually create subarrays.

...

I am actually concerned about a slightly more subtle issue. The use of subarrays means that the primitive is about as efficient as possible, no extra allocation is required. I am worried that LV will not recognize when it branches the wire and will create a copy, which it will not do for index array.

It may be better in later versions with more compiler optimizations, but some quick testing in LV9 shows that Delete from Array is *much* slower than Index Array. What I do is create a large array and read the last element N times using Delete from Array and then using Index Array (with the necessary math). No array changes, I simply read the same element repeatedly. Delete takes roughly 1 sec for my test, Index takes about 1 msec.

Link to comment

I am actually concerned about a slightly more subtle issue. The use of subarrays means that the primitive is about as efficient as possible, no extra allocation is required. I am worried that LV will not recognize when it branches the wire and will create a copy, which it will not do for index array.

Gotcha, my bad.

It may be better in later versions with more compiler optimizations, but some quick testing in LV9 shows that Delete from Array is *much* slower than Index Array. What I do is create a large array and read the last element N times using Delete from Array and then using Index Array (with the necessary math). No array changes, I simply read the same element repeatedly. Delete takes roughly 1 sec for my test, Index takes about 1 msec.

Eek! I really hope this isn't true anymore.

Link to comment

Eek! I really hope this isn't true anymore.

Crap, it looks like it is. :( In my benchmarks in LabVIEW 2012, it looks like the Delete From Array "trick" is about 30 times slower than using Index Array.

Oh well, I guess I won't use that trick anymore. Thankfully, Jarrod's Create Place VI Contents VI shortcut for Quick Drop made it really easy for me to add a shortcut to drop this code snippet instead:

post-4441-0-72857800-1349730963.png

  • Like 1
Link to comment
  • 5 weeks later...

I have a suggestion (back on topic to the original post). For the 1D to 2D VI you have a control for how many columns to make. Would it also be useful to have a control for the number of rows to make? I guess at that point there still is the choice of the order they are put into. So for instance I have an array.

[1, 2, 3, 4, 5, 6]

If I choose 2 rows how should the output look?

[1, 2

3, 4

5, 6]

Or

[1, 4

2, 5

3, 6]

My gut says it would be more useful to have the first but I could see uses for the second output.

Link to comment

This seems like a good CAR to file. Filed as CAR #377978.

Thanks for filing the CAR, Stephen...this thread fell off my radar.

Is this a CAR for the Delete From Array? I sure wish we had visibility into the CAR database...

Yes, Stephen CARed the Delete From Array performance issue.

Link to comment
No, it is index and the default is "last element" so I would want to see "index (last element)".
If we named it "index (last element)", that would be a lie. It is only by being unwired that you get the last element. There is no value you can pass in that will get you the last element. And it is named "index 0" in the context help because there are N indicies depending upon the dimensionality of the array, and the CH is trying to depict what happens for any dimensionality of array, but when you wire a 1D array, the terminal -- as it is on the diagram (see tip strip) -- is just "index" because there is no additional terminal that we need to differentiate.
Link to comment
  • 4 months later...
  • 2 months later...
  • 10 months later...

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.