Wednesday, December 15, 2010

How to Compare Something With Nothing

Nothin' from nothin' leaves nothin'
You gotta have somethin' if you wanna be with me
- Billy Preston, #1 hit, 1974

No, this hasn't suddenly become a blog about mid-70's R&B. As I considered the subject matter of this article, I just couldn't get this tune out of my head. Regardless, if you're not familiar with Mr. Preston's music, you might want to check it out. In addition to his successful, Grammy Award-winning career as a solo artist, Preston collaborated with some of the greatest names in the music industry, including The Beatles, The Rolling Stones, Ray Charles, Joe Cocker, Elton John, Eric Clapton, Bob Dylan, Aretha Franklin, Sly Stone, Johnny Cash, Neil Diamond, and the Red Hot Chili Peppers. Billy died in 2006.

And now back to our regularly scheduled programming. One of the many cool things which I love about LabVIEW is the ability of most of its primitives to be polymorphic. Similar to the general meaning in Computer Science, polymorphism is a programming language feature that allows values of different data types to be handled using a uniform interface. For example, the comparison palette is almost completely generic; you can use the same equality or inequality primitives for integers, floats, strings, enums, or arbitrarily complex compound structures (e.g. clusters) comprising all of the aforementioned. Particularly handy is LabVIEW's capacity to be polymorphic with arrays, which in many cases eliminates the need for looping. However, with this convenience comes behavior which may or may not suit your needs.

Consider the following code:
Notice that the two arrays are of different length. In this case, LabVIEW generates an output of the length of the shorter of the two arrays. Functionally, this is equivalent to the next code snippet which explicitly uses looping:

In the case of more than one array wired to the frame of a looping structure, auto-indexing works in a similar manner: the shortest array wired to the frame dictates the number of iterations. Maybe this is what you want. Then again, maybe not.

I recently encountered a case where I had a text ring array on a GUI which was used to allow the user to select, on the fly, which named tag values would be displayed on a corresponding array of doubles. A straightforward name-value pair display, with the twist of allowing the user to dynamically change which items appeared where in the list. This feature needed to be serviced whenever a selector was changed, and change detection was accomplished in the classic manner using a shift register to track previous values. However, the basic inequality primitive could not correctly handle when the list was made longer by the user. What was needed in this case was the ability to compare something against nothing. Here was my solution:

Not exactly rocket science. Perform the basic comparison, and at the same time figure out the difference in lengths between the two inputs. Determine the default behavior that you want when you compare a defined value against an undefined value, construct the correct length array with those values, and concatenate.

If there has to be one, I guess that the moral of the story is that sometimes these wicked cool oh-so-smart features built into LabVIEW do exactly the opposite of what you want them to. There ain't no such thing as a free lunch.


Dave S said...

"I guess that the moral of the story is that sometimes these wicked cool oh-so-smart features built into LabVIEW do exactly the opposite of what you want them to."

This is very true. Often--as in this case--there are solutions to be had that require a touch of additional code.

One thing I find particularly frustrating with the Labview community as a whole is the attitude that NI should provide built-in options for every situation where users might want to use something. Applied to your problem, instead of coming up with their own solution, someone might post an Idea Exchange request to add a right click option to the equals prim that iterates on the longer array instead of the shorter one.

(One of these days I'm going to post an idea to have Labview read my mind and write my app for me.)

Jim Kring said...

Hey Bob. Nice article/tip. Just a thought: If performance is an issue, using the "Max & Min" to get the max length and then reshaping the comparison array in place is probably (like this) the way to go. Cheers -Jim