The
following example appears throughout this section to illustrate how MATLAB
Function blocks exchange variable-size data with other Simulink^{®} blocks.
The model uses a variable-size vector to store the values of a white
noise signal. The size of the vector may vary at run time as the signal
values get pruned by functions that:

Filter out signal values that are not unique within a specified tolerance of each other

Average every two signal values and output only the resulting means

Open the example model by typing `emldemo_process_signal`

at
the MATLAB^{®} command prompt. The model contains the following blocks:

Simulink Block | Description |
---|---|

Band-Limited White Noise | Generates a set of normally distributed random values as the source of the white noise signal. |

MATLAB Function `uniquify` | Filters out signal values that are not unique to within a specified tolerance of each other. |

MATLAB Function `avg` | Outputs the average of a specified number of unique signal values. |

Unique values | Scope that displays the unique signal values output from the `uniquify` function. |

Average values | Scope that displays the average signal values output from the `avg` function. |

The band-limited white noise signal has these properties:

The size of the noise power value defines the size of the matrix that holds the signal values — in this case, a 1-by-9 vector of double values.

This block filters out signal values that are not within a tolerance of 0.2 of each other. Here is the code:

function y = uniquify(u) %#codegen y = emldemo_uniquetol(u,0.2);

The `uniquify`

function calls an external MATLAB function `emldemo_uniquetol`

to
filter the signal values. `uniquify`

passes the 1-by-9
vector of white noise signal values as the first argument and the
tolerance value as the second argument. Here is the code for `emldemo_uniquetol`

:

function B = emldemo_uniquetol(A,tol) %#codegen A = sort(A); coder.varsize('B',[1 100]); B = A(1); k = 1; for i = 2:length(A) if abs(A(k) - A(i)) > tol B = [B A(i)]; k = i; end end

`emldemo_uniquetol`

returns the filtered values
of `A`

in an output vector `B`

so
that `abs(B(i) - B(j)) > tol`

for all `i`

and `j`

.
Every time Simulink samples the Band-Limited White Noise block,
it generates a different set of random values for `A`

.
As a result, `emldemo_uniquetol`

may produce a different
number of output signals in `B`

each time it is called.
To allow `B`

to accommodate a variable number of
elements, `emldemo_uniquetol`

declares it as variable-size
data with an explicit upper bound:

coder.varsize('B',[1 100]);

In this statement, `coder.varsize`

declares `B`

as
a vector whose first dimension is fixed at 1 and whose second dimension
can grow to a maximum size of 100. Accordingly, output `y`

of
the `uniquify`

block must also be variable sized
so it can pass the values returned from `emldemo_uniquetol`

to
the **Unique values** scope. Here are
the properties of `y`

:

For variable-size outputs, you must specify an explicit size and upper bound, shown here as [1 9].

This block averages signal values filtered by the `uniquify`

block
as follows:

If number of signal values: | The MATLAB Function block: |
---|---|

> 1 and divisible by 2 | Averages every consecutive pair of values |

> 1 but not divisible by 2 | Drops the first (smallest) value and average the remaining consecutive pairs |

= 1 | Returns the value unchanged |

The `avg`

function outputs the results to the **Average values** scope. Here is the code:

function y = avg(u) %#codegen if numel(u) == 1 y = u; else k = numel(u)/2; if k ~= floor(k) u = u(2:numel(u)); end y = emldemo_navg(u,2); end

Both input `u`

and output `y`

of `avg`

are
declared as variable-size vectors because the number of elements varies
depending on how the `uniquify`

function block filters
the signal values. Input `u`

inherits its size from
the output of `uniquify`

.

The `avg`

function calls an external MATLAB function `emldemo_navg`

to
calculate the average of every two consecutive signal values. Here
is the code for `emldemo_navg`

:

function B = emldemo_navg(A,n) %#codegen assert(n>=1 && n<=numel(A)); B = zeros(1,numel(A)/n); k = 1; for i = 1 : numel(A)/n B(i) = mean(A(k + (0:n-1))); k = k + n; end

Simulating the model produces the following results:

The

`uniquify`

block outputs a variable number of signal values each time it executes:The

`avg`

block outputs a variable number of signal values each time it executes — approximately half the number of the unique values:

Was this topic helpful?