MastHEad

 


Props Inheritance


 

This page discusses the issue of Props Inheritance, meaning the rules and resulting behavior of how Kornucopia handles inheritance issues related to the Props Properties of entities of type k_units. In short, inheritance refers to what, if any, meta-info Properties (Description, ColNames, ColComments, ColUserData, RowNames, RowComments, RowUserData, and UserData) stored in the Props of an input argument are inherited by (or copied to) an output argument of a function or operation.  

Props Inheritance

All entities (variables, etc.) that are of data type k_units have the following Properties :

The Property Data holds the primary numeric values and Units holds the units string(s), if any, for the columns of numeric values. The Property Props holds all the other related sub-Properties .

When doing math on one or more entities, the rules of how to handle numeric values and their units are well established in science, engineering, and mathematics. However, rules for what to do with things like a variable description or column names are not well established in any of these disciplines!

Consider the following scenario. We have a variable, A, holding a few columns of data: time, force, and displacement. The columns have Units of 's', 'N', and 'mm' and ColNames of 'time', 'force', and 'disp'. If I create a new variable, C as C = -1*A, it is obvious what to do with the Data and Units, but what about the ColNames? Do we place a negative sign in front of the ColNames of C? Moreover, if we square each column of A via C = A .^2, how we do we derive the ColNames of C? Worse yet, we could choose to multiply the force column of A by the displacement column of A, and then divide by the time column A. What should the resulting ColNames be then? Now add to this adventure other Properties such as a Description or ColComments or UserData.  Not obvious what to do – we need some rules to go by!

The term Props Inheritance refers to the basic rules or behaviors of how, and if, a result inherits any of the Props from the input arguments that were used to calculate the result. This issue can occur in a variety of scenarios ranging from math-related operations like we just discussed to nearly any time a function is called. 

Kornucopia's guiding principle for Props Inheritance is to attempt, whenever it is reasonable and logical, to have the Props of the input arguments be inherited by the result of a calculation. For Kornucopia functions (function names beginning with "k_"), the rules of Props Inheritance for each function are stated on each function's help page. For math and math-related operations and functions, Kornucopia uses a set of rules to determine if inheritance should occur, and if so, how it occurs.  

We will begin with a discussion of how inheritance occurs, and then we discuss under what conditions inheritance occurs. To aid in the discussion, consider the case of computing C shown below.

C = A#B  or  C = func(A,B)

where # would represent a math operator such as C = A*B or C = A+B, and func would represent a math-related function like atan2.

Rules of inheritance

These rules apply whenever inheritance is to occur.

  1. If the number of columns of A and B are the same, then each of the sub-properties of C are inherited from the sub-Properties of A. For any sub-Properties of A that are empty, then those specific sub-Properties are inherited from B instead. 

  2. If the number of columns of A are greater than the number of columns of B, then all the sub-Properties for C are inherited from only A.

  3. If the number of columns of A are less than the number of columns of B, then all the sub-Properties for C are inherited from only B.

  4. If the function has more than 2 input arguments, inheritance is only derived from the first two input arguments. Props in the third or greater input arguments (if they exist) are ignored.

Conditions for when inheritance should occur

Kornucopia has, by default, automatic logic that determines when inheritance should occur and when it should not. In addition, Kornucopia provides user's with control over this behavior via the global Kornucopia ParamName 'inheritPropsWithMath'.  This ParamName can have one of three ParamVals, either 'auto' (the installed default), 'on', or 'off'.  You use the k_get  function to see this ParamName's current ParamVal and the k_set function to change its ParamVal.

For simplicity, we first describe what is done when inheritance is turned off, and then when it is turned on, and finally when it is set to auto (the installed default).

    1. If the operation or function causes the Units Signature of the output to be different from the Units Signature of the first input argument, then Props are not inherited, otherwise they are inherited. An exception to this rule is that if the operation is multiplication and either of the two arguments is dimensionless, then inheritance is applied. It is noted that a difference in Units Signature between input arguments and output results means that the fundamental base units constituents between input and output are different, such as is the case for units like N and Pa or N and kg. It is further noted that units such as N and lbf (or similar) have the same Units Signature (but their conversion factor is different) and thus they would satisfy the inheritance rule.

    2. If all the arguments but one in a given math operation are unitless (or have units of unity, percent, or strain), and there is not units in the denominator of a division operator, then inheritance is performed.

When the 'auto' setting is enabled and the result does NOT inherit Props due any combination of the logic stated above and the rules in the table below, then a warning stating "... the output result did NOT inherit any of the "Props" from the input argument(s). " is issued. If you desire to disable this warning, see the instructions near the top of this help page.

The table below details when inheritance occurs for various math operations and functions when
    k_get('inheritPropsWithMath') returns 'auto'.

Inheritance behavior when k_get('inheritPropsWithMath') returns 'auto'

 

Does output inherit input Props?

 Addition & subtraction operators (+, -)

Yes

 Multiplication operators (.*, *)

Yes if either input argument is unitless scalar (or is scalar with units of unity,  percent, or strain), otherwise no

 Division operators (./, /, .\, \)

In general no, but yes only if a quantity is being divided by a unitless scalar (or is scalar with units of unity,  percent, or strain)

 Summation of array elements function (sum)

Yes

 Product of array elements function (prod)

Yes if the input argument is unitless (or is with units of unity,  percent, or strain), otherwise no

Differences function (diff)

Yes, but with the following exceptions: when differencing across rows ColNames and ColComments are NOT inherited, when differencing down columns RowNames and RowComments are not inherited.

 Raise to power operators (^, .^) and

Yes if raised power = 1
 no otherwise

 Square root function (sqrt )

No

 Logs and exponent functions (log, log10, exp)

Yes

 Trigonometry functions (sin, cos, ...)

Yes

 Complex numbers and angles functions (abs, real, imag, conj, angle, unwrap)

Yes

 Descriptive statistics (mean, median, std, min, max)

Yes

 Truncation & rounding functions (ceil, floor, round)

 yes

 Vector cross product function (cross)
 Multi-Row Vector cross product function (k_rvecCross)

Yes if either input argument is a unitless entity (or is an entity with units of unity,  percent, or strain), otherwise no

 Vector dot product function (dot)
 Multi-Row Vector dot product function (k_rvecDot)

Yes** if either input argument is a unitless entity (or is an entity with units of unity,  percent, or strain), otherwise no.
 
**Note that in all cases, only sub-Props of Description, UserData, and DimensionNames are inheritable for dot product calculations, all other sub-Props are not.

 

Notes:

    1. Array concatenation functions and operators (cat, horzcat, vertcat, [] ), array flipping functions (flipud, fliplr, flipdim), and transpose functions and operators (transpose, .', ctranspose, ') always inherit the input argument's Props and their inheritance behavior is not influenced by the settings of 'inheritPropsWithMath' .

    2. Relational operators such as > or <= result in logical output values and not k_units data types, and thus the setting value of 'inheritPropsWithMath' does not influence the behavior of relational operators. To be clear, the operators can be applied to k_units data types; it is just that they only return MATLAB logical data type and thus they do not return any k_units Props.

    3. For matrix math operations M*N, M/N and M\N where both M and N are non-scalar matrices, Props are not inherited with 'auto' setting because ColNames, ColComments, and ColUserData (and similar) typically would not make sense. Also, any division operation that has units in the denominator will not inherit Props with the 'auto' setting for the same reason.