## Documentation Center |

On this page… |
---|

Overview of Approaches to Custom Statistics Graphical Block-Diagram Approach |

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.

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

Detect Changes in the Last-Updated Signal, which computes the ratio of an instantaneous queue length to its long-term average

The function-call subsystemfunction-call subsystem within the DVS Optimizer subsystem in the Modeling Load Within a Dynamic Voltage Scaling Application example

The Arrival Rate Estimation ComputationArrival Rate Estimation Computation subsystem within the Arrival Rate Estimator subsystem in the Estimating Entity Arrival Rates example

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

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.

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.

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.

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

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

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**

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

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.

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

Was this topic helpful?