Filter a Variable-Size Signal

About the Example

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

Simulink Model

Open the example model by typing emldemo_process_signal at the MATLAB® command prompt. The model contains the following blocks:

Simulink BlockDescription
Band-Limited White NoiseGenerates a set of normally distributed random values as the source of the white noise signal.
MATLAB Function uniquifyFilters out signal values that are not unique to within a specified tolerance of each other.
MATLAB Function avgOutputs the average of a specified number of unique signal values.
Unique valuesScope that displays the unique signal values output from the uniquify function.
Average valuesScope that displays the average signal values output from the avg function.

Source Signal

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.

MATLAB Function Block: uniquify

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 = uniquetol(u,0.2);

The uniquify function calls an external MATLAB function 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 uniquetol:

function B = 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

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, 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, 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 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].

MATLAB Function Block: avg

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 2Averages every consecutive pair of values
> 1 but not divisible by 2Drops the first (smallest) value and average the remaining consecutive pairs
= 1Returns 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 = nway(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 nway to calculate the average of every two consecutive signal values. Here is the code for nway:

function B = nway(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

Variable-Size Results

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?