LabVIEW MathScript RT Module

cancel
Showing results for 
Search instead for 
Did you mean: 

MathScript Nugget #12: Really advanced features of user-defined functions

In the past two nuggets, we covered basic and advanced features of creating and calling user-defined functions. Today we'll take it to the next level and cover a really advanced feature.

What makes this nugget so advanced? I mentioned in MathScript Nugget #11 that user-defined functions in MathScript are very similar to subVIs in LabVIEW. They're external code that you can call from your program and interact with in the Context Help, VI Hierarchy Window, and Error List. But user-defined functions are actually more powerful than subVIs in an interesting way: that's what makes this feature so advanced.

The inputs and outputs of a subVI have pre-defined data types. If you write your subVI to operate on a 1D array of DBL, then this is the only data type it will accept. If you try to wire in something else, LabVIEW will either break the wire or coerce the data to the expected type.

On the other hand, MathScript user-defined functions will accept any data type that you pass in. They will automatically adapt all of the code inside the user-defined function to be specefic for the datatypes that you pass in. The outputs will change datatypes too. This polymorphic behavior is similar to what you would expect from a LabVIEW primitive: if you connect a 1D array of booleans to the "Sort 1D Array" function, you will get a 1D array of booleans back, not a 1D array of doubles or integers. Same thing for MathScript user-defined functions!

How is this polymorphism useful? Suppose you've written an algorithm that can operate on a 2D array of any type and produce another 2D array of the same type. For example, say you have code to average the four quadrants of an array:

 

 

function B = QuadrantAverage(A)
[r c] = size(A);
if (mod(r,2)==1) || (mod(c,2)==1)
error('Dimension must be even');
else
rby2 = r/2; cby2 = c/2;
B = A(rby2+1:r, cby2+1:c) + A(1:rby2, 1:cby2) + A(1:rby2, cby2+1:c) + A(rby2+1:r, 1:cby2);
end

 

If you wanted to write this in LabVIEW as a subVI, you would have to write this algorithm for one specific data type. If you then wanted to use it for a 2D array of a different type, you would have to copy your subVI and manually change the types of the inputs and outputs. You could put the different subVIs in a polymorphic VI to let LabVIEW automatically select the correct algorithm, but you still need to create a subVI for each type that you want to use. In MathScript though, you only need to write your algorithm once and LabVIEW will automatically create the code for any data type that you call it with. If you call your function with a 2D DBL, the result is 2D DBL. Call it with integers or complex, then the result is integer or complex.

 

polymorphicUserFunc.PNG

This powerful feature of MathScript user-defined functions can be a real time saver. Enjoy!

jattas
LabVIEW MathScript R&D

ps Check out more MathScript Nuggets!

 

 

Message 1 of 3
(6,832 Views)

This is a great feature and I only hope that a similar handling of polymorpic inputs will trickle down to plain subVIs in future LabVIEW versions. For example if I have a subVI that only contains nodes that accept polymorphic inputs, we should be able to define the inputs and outputs of the subVI as "whatever type we wire to it" so the subVI will act identically to current simple nodes such as multiply, etc.

 

(If the subVI is not reentrant, only subVIs wired with the same data type would share code).

 

I think there is already an idea suggestion along those lines. 🙂

0 Kudos
Message 2 of 3
(6,805 Views)

Hi altenbach,

I strongly agree that it would be great to have this feature available for subVIs too. Hopefully this will come to pass in a future LabVIEW version.

Just to give you an idea of why it hasn't happened yet, there are all sorts of interesting problems associated with "generic" or "templatized" programming in LabVIEW.

N-dimensional arrays. Many LV nodes are polymorphic across all dimensions of arrays, but many are not. What if you wanted to write a VI that called a "scalar-in, scalar-out" subVI on every element of an array of any dimension and returned an array of the same dimensions? You would need something like a for loop that auto-indexes over every element of an N-D array. I could also imagine wanting indexing primitives that change more intelligently with arrays of different dimensions.

Type binding. Suppose you want to write a generic algorithm that searches a 1D array for a given value. You want the algorithm to operate on any type 1D array but you want to enforce that the type of the array must be the same as the type of the element you're searching for. What would be the UI to do this?

I'm not saying that either of these are unsolvable problems or that they're critical for every use case of the feature, but they're just a couple examples of the many, many, many interesting challenges of adding this feature to the rest of LabVIEW.

jattas
LabVIEW MathScript R&D

Message 3 of 3
(6,743 Views)