Run Rapid Simulations Over Range of Parameter Values

This example shows how to use the RSim target to run simulations over a range of parameter values. The example uses the Van der Pol oscillator and performs a parameter sweep over a range of initial state values to obtain the phase diagram of a nonlinear system.

It is very easy to customize this example for your own application by modifying the MATLAB® script used to build this example. Click the link in the top left corner of this page to edit the MATLAB® script. Click the link in the top right corner to run this example from MATLAB®. When running this example, make sure you are in a writable directory. The example creates files that you may want to investigate later.

For this example, Default parameter behavior is set to Inlined. In the example, you create Simulink.Parameter objects as tunable parameters. To use RSim with Default parameter behavior set to Tunable, and without explicitly declaring tunable parameters, see Run Batch Simulations Without Recompiling Generated Code.

To quickly run multiple simulations in the Simulink environment, consider using rapid accelerator instead of RSim. For information about rapid accelerator, see What Is Acceleration? (Simulink). To sweep parameter values, see Optimize, Estimate, and Sweep Block Parameter Values (Simulink).

Step 1. Preparation

Make sure the current directory is writable because this example will be creating files.

[stat, fa] = fileattrib(pwd);
if ~fa.UserWrite
    disp('This script must be run in a writable directory');

Open the model and configure it to use the RSim target. For more information on doing this graphically and setting up other RSim target related options, look here.

mdlName = 'rtwdemo_rsim_vdp';
cs = getActiveConfigSet(mdlName);

Specify as Tunable the variables INIT_X1 (the initial condition for state x1), INIT_X2 (the initial condition for state x2), and MU (the gain value). To create tunable parameters, convert the variables to Simulink.Parameter objects, and use a storage class other than Auto for each object. In this example we will be investigating how the state trajectories evolve from different initial values for the states x1 and x2 in the model.

INIT_X1 = Simulink.Parameter(INIT_X1);
INIT_X1.StorageClass = 'SimulinkGlobal';

INIT_X2 = Simulink.Parameter(INIT_X2);
INIT_X2.StorageClass = 'SimulinkGlobal';

MU = Simulink.Parameter(MU);
MU.StorageClass = 'SimulinkGlobal';

Define the names of files that will be created during this example.

prmFileName = [mdlName, '_prm_sets.mat'];
logFileName = [mdlName, '_run_scr.log'];
batFileName = [mdlName, '_run_scr'];
exeFileName = mdlName;
if ispc
    exeFileName = [exeFileName, '.exe'];
    batFileName = [batFileName, '.bat'];
aggDataFile = [mdlName, '_results'];
startTime = cputime;

Step 2. Build the Model

Build the RSim executable for the model. During the build process, a structural checksum is calculated for the model and embedded into the generated executable. This checksum is used to check that a parameter set passed to the executable is compatible with it.

### Starting build procedure for model: rtwdemo_rsim_vdp
### Successful completion of build procedure for model: rtwdemo_rsim_vdp

Step 3. Get the Default Parameter Set for the Model

Get the default rtP structure (parameter set) for the model. The modelChecksum field in the rtP structure is the structural checksum of the model. This must match the checksum embedded in the RSim executable (generated in step 2 above). If the two checksums do not match, the executable will generate an error. rsimgetrtp generates an rtP structure with entries for the named tunable variables INIT_X1, INIT_X2 and MU in the model.

rtp = rsimgetrtp(mdlName)
rtp = 

  struct with fields:

          modelChecksum: [1.7569e+09 1.8820e+09 853492625 1.7994e+09]
             parameters: [1x1 struct]
    globalParameterInfo: [1x1 struct]

Step 4. Create Parameter Sets

Using the rtp structure from step 4, we build a structure array with different values for the tunable variables in the model. As mentioned earlier, in this example we want to see how the state trajectories evolve for different initial values for the states x1 and x2 in the model. Hence we generate different parameter sets with different values for INIT_X1 and INIT_X2 and leave the tunable variable MU at the default value.

INIT_X1_vals = -5:1:5;
INIT_X2_vals = -5:1:5;
MU_vals = 1;
nPrmSets = length(INIT_X1_vals)*length(INIT_X2_vals)*length(MU_vals)
nPrmSets =


Note that in this example we have nPrmSets parameter sets, i.e., we need to run that many simulations. Initialize aggData, which is a structure array used to hold the parameter set and the corresponding results.

aggData = struct('tout', [], 'yout', [], ...
                'prms', struct('INIT_X1',[],'INIT_X2',[], 'MU', []))
aggData = repmat(aggData, nPrmSets, 1);
aggData = 

  struct with fields:

    tout: []
    yout: []
    prms: [1x1 struct]

The utility function rsimsetrtpparam is a convenient way to build the rtP structure by adding parameter sets one at a time with different parameters values.

idx = 1;
for iX1 = INIT_X1_vals
    for iX2 = INIT_X2_vals
        for iMU = MU_vals
            rtp = rsimsetrtpparam(rtp,idx,'INIT_X1',iX1,'INIT_X2',iX2,'MU',iMU);
            aggData(idx).prms.INIT_X1 = iX1;
            aggData(idx).prms.INIT_X2 = iX2;
            aggData(idx).prms.MU      = iMU;
            idx = idx + 1;

Save the rtP structure array with the parameter sets to a MAT-file.


Step 5. Create a Batch File

We create a batch/script file to run the RSim executable over the parameter sets. Each run reads the specified parameter set from the parameter MAT-file and writes the results to the specified output MAT-file. Note that we use the time out option so that if a particular run were to hang (because the model may have a singularity for that particular parameter set), we abort the run after the specified time limit is exceeded and proceed to the next run.

For example, the command (on Windows®)

  model.exe -p prm.mat@3 -o run3.mat -L 3600 2>&1>> run.log

specifies using the third parameter set from the rtP structure in prm.mat, writing the results to run3.mat, and aborting execution if a run takes longer than 3600 seconds of CPU time. In addition, messages from model.exe while it is running are piped to run.log. In case of problems, we can look at run.log to help debug.

fid = fopen(batFileName, 'w');
idx = 1;
for iX1 = INIT_X1_vals
    for iX2 = INIT_X2_vals
        for iMU = MU_vals
            outMatFile = [mdlName, '_run',num2str(idx),'.mat'];
            cmd = [exeFileName, ...
                   ' -p ', prmFileName, '@', int2str(idx), ...
                   ' -o ', outMatFile, ...
                   ' -L 3600'];
            if ispc
                cmd  = [cmd, ' 2>&1>> ', logFileName];
            else % (unix)
                cmd  = ['.' filesep cmd, ' 1> ', logFileName, ' 2>&1'];
            fprintf(fid, ['echo "', cmd, '"\n']);
            fprintf(fid, [cmd, '\n']);
            idx = idx + 1;
if isunix,
    system(['touch ', logFileName]);
    system(['chmod +x ', batFileName]);

Creating a batch file to run the simulations enables us to call the system command once to run the simulations (or even run the batch script outside MATLAB®) instead of calling the system command in a loop for each simulation. This results in a performance improvement because the system command has significant overhead.

Step 6. Execute Batch File to Run Simulations

Run the batch/script file, which runs the RSim executable once for each parameter set and saves the results to a different MAT-file each time. Note that this batch file can be run from outside MATLAB®.

[stat, res] = system(['.' filesep batFileName]);
if stat ~= 0
    error(['Error running batch file ''', batFileName, ''' :', res]);

In this example we put the simulation runs into one batch file, ran the batch file to sequentially run 'n' simulations over 'n' parameter sets. For your application this script can be modified to generate multiple batch files, and these batch files are run in parallel by distributing them across multiple computers. Also the batch files can be run without launching MATLAB®.

Step 7. Load Output MAT-files and Collate the Results

Here we collect the simulation results from the output MAT-files into the aggData structure. If the output MAT-file corresponding to a particular run is not found, we set the results corresponding to that run to be NaN (not a number). This situation can occur if a simulation run with a particular set of parameters encounters singularities in the model.

idx = 1;
for iX1 = INIT_X1_vals
    for iX2 = INIT_X2_vals
        for iMU = MU_vals
            outMatFile = [mdlName, '_run',num2str(idx),'.mat'];
            if exist(outMatFile,'file')
                aggData(idx).tout = rt_tout;
                aggData(idx).yout = rt_yout;
                aggData(idx).tout = nan;
                aggData(idx).yout = nan;
            idx = idx + 1;

Save the aggData structure to the results MAT-file. At this point, you can delete the other MAT-files, as the aggData data structure contains the aggregation of input (parameters sets) and output data (simulation results).

disp(['Took ', num2str(cputime-startTime), ...
      ' seconds to generate results from ', ...
      num2str(nPrmSets), ' simulation runs (Steps 2 to 7).']);
Took 13.53 seconds to generate results from 121 simulation runs (Steps 2 to 7).

Step 8. Analyze Simulation Results

We now have data to plot the phase diagram (X2 versus X1) with different initial values for x1 and x2. The diagram shows that, irrespective of the initial condition, the Van der Pol oscillator converges to its natural oscillator mode.

colors = {'b','g','r','c','m','y','k'}; nColors = length(colors);
for idx = 1:nPrmSets
    col = colors{idx - nColors*floor(idx/nColors) + 1};
    plot(aggData(idx).prms.INIT_X1, aggData(idx).prms.INIT_X2, [col,'x'], ...
         aggData(idx).yout(:,1), aggData(idx).yout(:,2),col);
    hold on
grid on
title('Phase diagram for Van der Pol equation');

Was this topic helpful?