One of the ways Kornucopia makes MATLAB syntax easier is to allow use of Kornucopia-compatible data types in many expressions intended for input arguments of data type k_units. To explain how this works and benefits you, we first define what makes a Kornucopia-compatible data type.
Simply put, a Kornucopia-compatible data type is any data type (or entity), A, that can be successfully converted to a k_units data type of the class k_units (denoted as B, below) via
B = k_units(A).
The Kornucopia function k_units, in the expression above, is also called the constructor function for the class k_units. Data types (or entities) that yield an error for this function evaluation are not Kornucopia-compatible data types.
Here is a helpful link for a more general discussion of The k_units Data Type.
Kornucopia enhances MATLAB syntax flexibility because it allows users to input entities of type k_units and/or Kornucopia-compatible data types into all Kornucopia functions and many Kornucopia-overloaded MATLAB operators and functions. All of these Kornucopia-related functions and operators are designed with the following logic:
Each input argument that technically should be of a k_units data type is checked for its type.
If the input is of type k_units, it is passed into the function or operator "as is".
If the input is not of type k_units, then Kornucopia
internally temporarily attempts to convert the input argument to a
k_units data type via
B = k_units(A), where A
denotes the given input argument. Note that this is an
internal temporary conversion, meaning Kornucopia does not actually
change the input's actual data type in the workspace in which the
input exists.
The MATLAB data types that are Kornucopia-compatible are described below (A is the assumed name of the input entity):
MATLAB datetime and duration data types for scalars and 2-D arrays.
Kornucopia copies the input A to the temporary internal variable tmp.
If tmp is a datetime data type, Kornucopia temporarily internally converts tmp to a MATLAB duration data type via the following steps:
start_datetimes = tmp(1,:);
tmp = tmp - start_datetimes; (This math operation changes tmp from a datetime data type to a duration data type.)
The internal variable tmp (which is a duration data type) is next converted to a double data type holding the value of the duration in seconds via
tmp = seconds(tmp);
Lastly, the following set of steps are performed:
B = k_units(tmp, 's');
B = B.convert(); (This converts the units of time to the current active Units Preference).
If the original input was a datetime data type, then a struct with field name start_datetimes is placed into B.Props.ColUserData to store the starting datatime of that column.
MATLAB table and timetable data types
The table must be "flat" (no sub-columns).
Kornucopia copies the input A to the temporary internal variable tmp.
If the input tmp is a timetable data type, Kornucopia temporarily internally converts tmp to a MATLAB table data type via
tmp = timetable2table(tmp). This action results in a column with the name Timestamp being prepended to the variable tmp which is now a table data type.
All columns in tmp that are of data type datetime or duration are processed as described above for MATLAB datetime and duration data types. All the other columns contents of tmp must be convertible to the MATLAB data type of double. The complete Property mapping of a MATLAB table to a k_units data type is listed below:
tmp{:,:} → B.Data (This is a high level simplistic description. The actual process assesses and processes any columns in tmp that are of data type datetime and/or duration).
tmp.Properties.VariableUnits → B.Units
tmp.Properties.Description → B.Props.Description
tmp.Properties.VariableNames → B.Props.ColNames
tmp.Properties.VariableDescriptions → B.Props.ColComments
tmp.Properties.RowNames → B.Props.RowNames
tmp.Properties.UserData → B.Props.UserData
tmp.Properties.DimensionNames → B.Props.DimensionNames
Notes:
MATLAB tables do not have a RowComments Property, so B.Props.RowComments takes the Kornucopia empty default of {}.
MATLAB tables do not have column and row-based UserData, so B.Props.RowUserData and B.Props.ColUserData take the Kornucopia empty default of {} each.
Any scalar or 2-D array which can be converted to the MATLAB data type of double via double(A) is Kornucopia-compatible data type.
A structure having the following field names exactly (including case) as defined below:
StructWas_k_units - Holds the value of true (1) or false (0), indicating that the struct was originally a k_units data type that had been converted to a struct via the .toStuct method or k_unitsToStruct function. Please note that this field, StructWas_k_units, must be included for Kornucopia to consider the input to be potentially a compatible k_units data type.
Data - A required field that holds a scalar or 2-D array which can be converted to the MATLAB data type of double.
Units - A required field holding an empty or a cell-string of units strings or mathematical combinations of units strings.
Props - An optional field that contains the following optional sub-fields
Description - An empty, a string, or a cell-string holding a general description for the variable.
ColNames - An empty or a cell-string holding column names for each of the columns of Data.
ColComments - An empty or a cell-string holding column comments for each of the columns of Data.
ColUserData - This is an optional field. If supplied, it is an empty or a cell array holding column-based UserData for each of the columns of Data.
RowNames - An empty or a cell-string holding row names for each of the rows of Data.
RowComments - An empty or a cell-string holding row comments for each of the rows of Data.
RowUserData - This is an optional field. If supplied, it is an empty or a cell array holding row-based UserData for each of the rows of Data.
UserData - An empty or any MATLAB or Kornucopia data type. UserData can essentially hold any data type MATLAB supports.
DimensionNames - An empty or a 1x2 cell-string defining the names for the rows and columns.
A char-string** for which k_units(A)
returns a valid k_units data
type. Listed below are several examples to show you the flexibility
possible. The item to the left of the arrow is the string definition
of a variable and the result to the right of the arrow is how Kornucopia
will interpret the string when it internally processes it with the
function k_units
.
A = 'mm'
→ B = 1*mm
.
A = '5*N/mm^2'
→ B = 5*N/mm^2
.
A = '10'
→ B = 10
. (Note: B
is of k_units data type, it just
happens to have dimensionless units)
** Please note that with k_units variable, the use of char-strings (with single quotes) is allowed but the newer MATLAB string data type with double quotes is generally not supported. In much of Kornucopia's documentation, the char-string is simply stated or described as string. Unless explicitly stated that this is meant to imply the double quoted MATLAB string data type, we mean to imply a char-string. Sorry if this creates any confusion.
Below we demonstrate a few typical usage cases. The yellow highlighted region denotes the specific location of its use in the example.
Example 1
Consider the case of integrating acceleration,a
, with respect to time,t
, where each variable is a vector of data type k_units. We need to include an initial velocity ofVo = -20*m/s
in the integration. We use the k_integrate function to directly and easily integrate the data, including the initial conditionVo
. The integration function expects input arguments of type k_units or Kornucopia-compatible data types.Below we show two "explicit" ways to perform the integration calculation.
Method A
Vo = k_units(-20, 'm/s')
V = k_integrate(t, a, Vo)Method B
k_unitsVariables('m, s')
Vo = -20*m/s
V = k_integrate(t, a, Vo)Method A uses the function k_units to explicitly create the variable
Vo
, which is now of a k_units data type. Method B uses the function k_unitsVariables to easily create two variables in the MATLAB workspace,m
ands
. These variables represent 1 meter and 1 second, respectively, and both are of data type k_units. We then use natural math notation to defineVo
, which becomes of type k_units because doing math with any entity of data type k_units results in a quantity of data type k_units.Below is a syntax that takes advantage of entering the initial velocity as a char-string (a Kornucopia-compatible data type).
Method C
V = k_integrate(t, a, '-20*m/s')
In the Method C syntax, the function
k_integrate
internally converts, as described previously, the string'-20*m/s'
to an argument of type k_units during its processing.For completeness, it is noted that either or both the variables
t
anda
could have been MATLAB tables (or some other Kornucopia-compatible data type) instead of k_units typed variables. Just like with the initial velocity argument, the k_integrate function would have internally temporarily converted these other arguments to k_units data type while doing its evaluation. Moreover, had the integration been with a quantity that was dimensionless or had no units, then the input arguments could have also been a numeric array of data (since such an array has no units).
This next example demonstrates a few math operations, including some using Kornucopia-compatible data types.
Example 2
Following from example 1 above, consider that the variablea
is a k_units typed column vector of acceleration and has appropriate units associated with it. The variablea
represents the acceleration of a body moving in space over time. If the body has a mass, sayM = 5*kg
, then we can compute the inertial force viaF = M*a
.Three different explicit approaches to compute the force are:
Method A
M = k_units(5, 'kg')
F = M*aMethod B
k_unitsVariables('kg')
F = (5*kg)*aMethod C
k_unitsVariables('kg')
M = 5*kg
F = M*aHere is an approach that uses a Kornucopia-compatible syntax of a string in the math expression (highlighted in yellow)
Method D
F = '5*kg'*a
In the Method D approach, MATLAB's times operator,
*
, sees two arguments presented to it, the string'5*kg'
and the variablea
which holds a k_units data type. Since Kornucopia has overloaded this MATLAB times operator, MATLAB passes the calculation to Kornucopia because at least one argument of the operator was of data type k_units. This allows Kornucopia to then recognize and convert the string input to a k_units typed argument and complete the multiplication operation. This type of behavior works with + and over 80 other MATLAB operators and functions (see Overloaded MATLAB Functions ).
Please note: Using char-strings (or any other Kornucopia-compatible data type) for BOTH arguments in such a math operation will either give an error or produce an unexpected non-Kornucopia result. This is because when MATLAB looks to initially evaluate the operation, it does NOT see any k_units typed inputs and thus it never passes the calculation to Kornucopia. Without passing the calculation to Kornucopia, the standard MATLAB evaluation will be executed which will typically fail or give unintended results.
Thus, this will NOT work:
F = '5*kg'*'8*m/s^2'
. There is no k_units data types in the expression.