Data collection


In previous section, different datatype and formats to represent data was presented. How to represent a collection of these datas is explored in this section.

Overview

Workbench inherently supports three data collections:

  1. Native data

  2. Matrix data

  3. Mux data

The most primitive data collection is Native, which represents a single entity. A variable containg just a single data of type Integer, Double, Boolean etc., is considered as Native. Both Matrix and Mux datas are formed by collection of Native datas. A Matrix collection as the name indicates, represents matrices. All elements within a Matrix must be of same data type. It can be of any dimension, but sub-matrices within it must be of uniform size. Mux is merely a virtual collection of data for ease of handling and does not have any physical implications. Native datas of any data type can be mux-ed together to form a virtual collection. Here is a list of examples showing how to create the different collections:

Examples Collection type Data type Comments
3.3 Native Double -
|s|3 Native Short -
True Native Boolean -
[|i|3, |i|2, |i|1] Matrix Integer Row matrix with three Native Integer elements within it.
[[3.3, 2.2, 1.1]] Matrix Double Column matrix, 3x1. To increase the dimension, an extra [ ] (brackets) is added.
[3] Matrix Double Single element row matrix. This is functionally same as a Native data. But, to represent a single element, Native data is to be preferred over Matrix since the former is much more optimized in terms of both memory and computational performance.
[[3]] Matrix Double Single element column 1x1 matrix.
[[6.6, 5.5, 4.4], [3.3, 2.2, 1.1]] Matrix Double 2x3 2D matrix with two rows and three columns./td>
[[[6.6, 5.5, 4.4]], [[3.3, 2.2, 1.1]]] Matrix Double 2x1x3, 3D matrix. Simply adding [ ] (brackets) increases the dimension by 1.
[[[6.6], [5.5], [4.4]], [[3].3, [2.2], [1.1]]] Matrix Double 2x3x1, 3D matrix. Simply adding [ ] (brackets) increases the dimension by 1.
[True, False, True] Matrix Boolean Boolean row matrix.
[|i|3, |i|2, 1] Matrix Double The first two elements are Integers and, the last element has no type qualifier and hence by default considered as Double. The whole collection itself is set to Double to accomadate all the elements. Each non-Double element is implicitly type-casted to Double before being stored in the matrix.
[[6.6, 5.5, 4.4], [3.3, 2.2]] Invalid Double Invalid data collection. Every sub matrix must be of same size. The first row has 3 columns while second row has 2 columns.
[|i|3, |i|2, True] Invalid Invalid Invalid data collection. Cannot mix Boolean and Numeric data types within same matrix, since there is no implicit type-cast from Boolean to Numeric type.
{|i|3, 2.2, True} Mux {Integer, Double, Boolean} Mux data. A linear collection of any type of data enclosed within { } (braces)

The examples shown above can be used in tool properties. All arithmetic operations on Matrix collection invoke corresponding dot or cross operators. Matrix can contain just a single element within it, which is similar in functionality to a Native element but has significant perfomance cost, since Native elements are highly optimized for both memory utllization and computational speed. All operations on a Mux collection invokes element by element, operation. Mux unlike Matrix must have more than single element within it. As mentioned earlier, Mux is a virtual collection, and there is no memory allocated for these variables. At compile-time any operation involving Mux collection is resolved to each of the element in the collection.

To create or resolve a Mux collection in the model, use the Signal Routing - Mux and Signal Routing - De-mux tools available in the Signal Routing toolbox. Similarly to merge, split or access specific element of a Matrix use the tools available in the Matrix Manipulation toolbox.

Implicit data type and collection cast

All tools implicitly cast numeric data type inputs to a common data type before carrying out any arithmetic operation. The data type to which it is casted to is decided, based on the choice that leads to the least possiblity of data loss. It happens to be in the following order: Double, Single, Long, Integer and Short. This is known as implicit up-cast. For instance, if a data of Integer type is added to data of Long type, the former is internally casted to Long before the addition operation. The resultant is of Long data type. Similarly if a data of Long data type is multiplied with data of type Double, the former is casted to Double before the operation and the resultant is of type Double.

Certain operations will always result in fixed output data type irresepective of the inputs' data types. For instance, when two numbers are divided, the output is always of type Double irrespective of inputs' data types. Similarly, the output of an intergator or differentiator is always of type Double. This is because the former internally involves multiplication with step time, Δt, which of type Double and the latter involves division by Δt. In few cases, implicit down-cast could occur. This could lead to loss of data or unexpected behavior and the compiler will always throw a warning in these cases. For example, the index input of Conditional Selector - Index-based Selector, must be of Integer type. If the index input was of type Short, then there is no issue, since it is implicity up-casted to type Integer which leads to no loss of data. But if the index input is of type Double, Single or Long, it is implicitly down-casted which could lead to loss of data and undexpected behavior. When data of floating point type such as Double and Single is down-casted to Integer type, the fractional part is ignored. The number is not rounded off the nearest integer. This is to maintain functional uniformity with, C89 standard C-code generated by default during real-time code generation, where implicit down-cast leads to ignoring the fractional part rather than rounding off to nearest integer.

Similar to data type casting, data collection is casted as well such that the choice leads to no data loss. In case of data collection, there are just two choices for casting namely, Native or Matrix since Mux collection is just a virtual collection. When two inputs, one of Native and other of Matrix collection are added, the resultant is a Matrix. Even when the resultant of an operation is expected to be of size 1, the resultant will be a Matrix if any of the input is a Matrix. For instance, if a 3x1 column matrix is multipled with a 3 element row matrix, the result is just a single element. The compiler outputs this as a matrix of size 1 and dimension 1 rather than as a Native. This is because, unlike data type, the dimensions are known only at run time and not during compile time. As mentioned earlier, Native collection is much more optimized that Matrix and hence it will be advantageous to explicity cast the output to Native using Signal Conversion/Matrix Manipulation - To-Element if it is known for certain that the output will be a matrix with just a single element.

In certain cases, an implicit down-cast of data collection from Matrix to Native happens. In such cases, similar to data type down-cast, a warning is thrown. For instance, in case of Conditional Selector - Index-based Selector, when it is set to optimize conditional evaluation, the index cannot be a Matrix. In this case, if the input is a Matrix, it is implicity down-casted to Native element. If the matrix has more than one element, the cast will throw a run-time exception in simulation mode. In real-time mode, these checks are not performed to catch such errors in favor of faster performance and hence would lead to unexpected behavior.

Data type and collection cast can both happen at the same time. For instance if a Matrix of Integer type is added to a Native of Double type, the former is first casted to Matrix of Double type and the operation is performed, with the resultant being a Matrix of Double data type. Anytime an implicit down-cast warning is thrown, it might be advantageous to fix it by using a typecast tool and verifying it works as expected in simulation before transitioning to real-time mode.



< Data type and format : previous topic