Jump to content
News about the LabVIEW Wiki! Read more... ×
crossrulz

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

Share this post


Link to post
Share on other sites

I don't have a computer that has LabVIEW to open the 1D <-> 2D, so you may have to forgive the question: How are these different than Reshape Array?

Share this post


Link to post
Share on other sites

They actually use the Reshape array. But the math for how to setup the dimentions is done inside these VIs.

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites

Yeah, my benchmarks found that the delete from array was really slow. What I ended up doing in the proposed VI was to reverse the array and then index the first element. This method was slightly faster than the index array size -1.

  • Like 1

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
Share on other sites

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

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

  • Like 2

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites

There's a reason I try never to promise future functionality. The fix is being backed out of 2013 and will be reattempted for 2014. No promises.

Share this post


Link to post
Share on other sites
There's a reason I try never to promise future functionality. The fix is being backed out of 2013 and will be reattempted for 2014. No promises.

Assuming 2013 or 2014 even ship ;)

Share this post


Link to post
Share on other sites
Assuming 2013 or 2014 even ship ;)

 

Don't freak us out there...

  • Like 1

Share this post


Link to post
Share on other sites

Ok. I think we have it right this time. At the very least, it passes validation on today's token. CAR #377978 appears to be fixed in LabVIEW 2014 -- the input to Delete From Array is no longer a stomper if the output array is unwired.

Share this post


Link to post
Share on other sites

"Stomper" huh? Interesting terminology given the context.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×

Important Information

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