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.
Note: If you have come to this help page because you clicked on a "learn more" link in a warning stating "... the output result did NOT inherit any of the "Props" from the input argument(s). ", this page will help you understand why the warning was issued.
If you are looking to disable the
warning, simply issue the following command at the beginning
of your m-file or at the MATLAB command prompt:
k_set('inheritPropsAutoWarning',
'off')
To turn the warnings back on, use 'on' instead of 'off' in the function above. You can
also inquire the current status of the setting via:
k_get('inheritPropsAutoWarning')
Lastly, if you want the warning off for all your MATLAB
sessions, place the command in your afterKornucopiaStart.m
file.
All entities (variables, etc.) that are of data type k_units have the following Properties :
Data
Units
Props
Description
ColNames
ColComments
ColUserData
RowNames
RowComments
RowUserData
UserData
DimensionNames
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.
These rules apply whenever inheritance is to occur.
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.
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.
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.
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.
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).
When k_get('inheritPropsWithMath') returns the value 'off', then inheritance does NOT occur. Hence, C (from the syntax example earlier) does not inherit the Props of the input arguments and no warnings regarding this lack of inheritance are issued, regardless of the global Kornucopia ParamVal of 'inheritPropsAutoWarning' (see k_get or k_set for more info).
When k_get('inheritPropsWithMath') returns 'on', then inheritance occurs with a partial exception that is noted below. Hence, C inherits the Props of the input arguments.
Partial exception - for matrix math operations of M*N, M/N and M\N, where both M and N are non-scalar matrices, only inheritance of Props.Descriptions and Props.UserData occurs because the inheritance of ColNames and ColComments (and similar row properties) is highly likely to not make sense.
When k_get('inheritPropsWithMath') returns 'auto', then the inheritance behavior of C depends on the specific math operator or function as described in the table below. The basic goal of the 'auto' setting is to attempt, when reasonable, to have the output result inherit Props from the input arguments. The general principles that are used to determine when to inherit and when not to inherit Props for the 'auto' setting are:
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.
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 otherwiseSquare 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:
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' .
For the functions vertcat or cat (using dim argument of 1), the functions uses the first non-empty argument as the master for determining Units and ColNames Properties. For the ColComments, ColUserData, Description, and UserData properties, the first non-empty value for each property found is used. Note that any input variables for which the MATLAB function isempty returns true are skipped in their entirety (all Data, and Props are ignored).
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.
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.