Accelerating the pace of engineering and science

Documentation Center

• Trial Software

Derive Custom Statistics

Overview of Approaches to Custom Statistics

You can use the built-in statistical signals from SimEvents® blocks to derive more specialized or complex statistics that are meaningful in your model. One approach is to compute statistics during the simulation. You can implement your computations using a graphical block-diagram approach or a nongraphical coded approach. Alternatively, you can compute statistics after the simulation is complete.

Graphical Block-Diagram Approach

The Math Operations library in the Simulink® library set and the Statistics library in the DSP System Toolbox™ library set can help you compute statistics using blocks. For examples using Simulink blocks, see

Coded Approach

The blocks in the User-Defined Functions library in the Simulink library set can help you compute statistics using code. For examples using the MATLAB Function block, see

Post-Simulation Analysis

You can use the Discrete Event Signal to Workspace block to log data to the MATLAB® workspace and compute statistics after the simulation is complete.

Fraction of Dropped Messages

The example below shows how to compute a ratio of event-based signals in a subsystem that executes when either signal has a sample time hit. The Output Switch block either transmits or drops the message corresponding to each entity. The goal is to compute the fraction of dropped messages, that is, the fraction of entities that depart via OUT2 as opposed to OUT1 of the Output Switch block.

Upper-Level System

Subsystem Contents

Two Entity Sink blocks produce #a signals that indicate how many messages the communication link transmits or drops, respectively. The subsystem divides the number of dropped messages by the sum of the two #a signals. Because the subsystem performs the division only when one of the #a signals increases, no division-by-zero instances occur.

Compute a Time Average of a Signal

This example (open modelmodel) illustrates how to compute a time average of a signal using the MATLAB Function block, and especially how to make the block retain data between calls to the function.

The model below implements a simple queuing system in which the FIFO Queue produces the output signals

• #n, the instantaneous length of the queue

• len, the time average of the queue length; this is the time average of #n.

Top-Level Model

The subsystem uses #n to compute the time average. In this case, the time average should equal len. You can use a similar subsystem in your own models to compute the time averages of other signals.

Computation of the Time Average

In the example, the subsystem performs computations each time a customer arrives at or departs from the queue. Within the subsystem, the MATLAB Function block keeps a running weighted sum of the #n values that form the input, where the weighting is based on the length of time over which the signal assumes each value.

The block uses persistent variables for quantities whose values it must retain from one invocation to the next, namely, the running weighted sum and the previous values of the inputs.

Below are the subsystem contents and the function that the MATLAB Function block represents.

Subsystem Contents

```function y = timeavg(u,t)
%TIMEAVG Compute time average of input signal U
%   Y = TIMEAVG(U,T) computes the time average of U,
%   where T is the current simulation time.

% Declare variables that must retain values between iterations.
persistent running_weighted_sum last_u last_t;

% Initialize persistent variables in the first iteration.
if isempty(last_t)
running_weighted_sum = 0;
last_u = 0;
last_t = 0;
end

% Update the persistent variables.
running_weighted_sum = running_weighted_sum + last_u*(t-last_t);
last_u = u;
last_t = t;

% Compute the outputs.
if t > 0
y = running_weighted_sum/t;
else
y = 0;
end```

Verifying the Result

After running the simulation, you can verify that the computed time average of #n is equal to len.

```isequal([len.time, len.signals.values],...
[len_computed.time, len_computed.signals.values])
```

The output indicates that the comparison is true.

```ans =

1```

Reset an Average Periodically

This example (open modelmodel) illustrates how to compute a sample mean over each of a series of contiguous time intervals of fixed length, rather than the mean over the entire duration of the simulation. The example simulates a queuing system for 4 weeks' worth of simulation time, where customers have access to one server during the first 2 days of the week and five servers on the other days of the week. The average waiting time for customers over a daily cycle depends on how many servers are operational that day. However, you might expect the averages taken over weekly cycles to be stable from one week to the next.

The model below uses a time-based Repeating Sequence Stair block to determine whether entities advance to a Single Server or N-Server block, thus creating variations in the number of operational servers. The Start Timer and Read Timer blocks compute each entity's waiting time in the queuing system. A computational subsystem processes the waiting time by computing a running sample mean over a daily or weekly cycle, as well as the final sample mean for each cycle. Details about this subsystem are in Computation of the Cycle Average.

Top-Level Model

Performance of Daily Averages

When considering daily cycles, you can see that the cycle averages do not stabilize at a single value.

Performance of Weekly Averages

When considering weekly cycles, you can see less variation in the cycle averages because each cycle contains the same pattern of changing service levels. To compute the cycle average over a weekly cycle, change the Period parameter in the Time-Based Entity Generator1 block at the bottom of the model to 60*60*24*7, which is the number of seconds in a week.

Computation of the Cycle Average

In the example, the subsystem performs computations each time a customer departs from the queuing system and at each boundary of a daily or weekly cycle. Within the subsystem, the MATLAB Function block counts the number of customers and the total waiting time among all customers at that point. The block resets these quantities to zero at each boundary of a cycle.

The block uses persistent variables for quantities whose values it must retain from one invocation to the next. The number of customers and total waiting time are important to retain for the computation of an average over time rather than an instantaneous statistic. Previous values of inputs are important to retain for comparison, so the function can determine whether it needs to update or reset its statistics.

The outputs of the MATLAB Function block are

• runningavg, the running sample mean of the input waiting times

• cycleavg, a signal that, at reset times, represents the sample mean over the cycle that just ended

Below are the subsystem contents and the function that the MATLAB Function block represents.

Subsystem Contents

```function [runningavg, cycleavg] = fcn(d,et,reset)
%FCN    Compute average of ET, resetting at each update of RESET
%   [RUNNINGAVG,CYCLEAVG] = FCN(D,ET,RESET) computes the average
%   of ET over contiguous intervals. D is the number of samples
%   of ET since the start of the simulation. Increases in
%   RESET indicate when to reset the average.
%
%   Assume this function is invoked when either D or RESET
%   (but not both) increases. This is consistent with the
%   behavior of the AtomicSubsystem block that contains
%   this block in this example.
%
%   RUNNINGAVG is the average since the start of the interval.
%
%   At reset times, CYCLEAVG is the average over the interval
%   that just ended; at other times, CYCLEAVG is 0.

% Declare variables that must retain values between iterations.
persistent total customers last_reset last_d;

% Initialize outputs.
cycleavg = 0;
runningavg = 0;

% Initialize persistent variables in the first iteration.
if isempty(total)
total = 0;
customers = 0;
last_reset = 0;
last_d = 0;
end

% If RESET increased, compute outputs and reset the statistics.
if (reset > last_reset)
cycleavg = total / customers; % Average over last interval.
runningavg = cycleavg; % Maintain running average.
total = 0; % Reset total.
customers = 0; % Reset number of customers.
last_reset = reset;
end

% If D increased, then update the statistics.
if (d > last_d)
total = total + et;
customers = customers + 1;
last_d = d;
runningavg = total / customers;
end```