Discover MakerZone

MATLAB and Simulink resources for Arduino, LEGO, and Raspberry Pi

Learn more

Discover what MATLAB® can do for your career.

Opportunities for recent engineering grads.

Apply Today

To resolve issues starting MATLAB on Mac OS X 10.10 (Yosemite) visit: http://www.mathworks.com/matlabcentral/answers/159016

How do I get random numbers from a Simulink Coder executable?

Asked by David on 14 Feb 2013

I have a simple Simulink model that consists of a Random Number block and a To File block that writes the random number to a file. I compile this using Simulink Coder and get an executable. Every time I run the executable I get the same number. I would like to find a way to make it so that every time I run the executable I get a different number.

There was a similar problem asked here which was apparently solved, though the solution was not given. I assume that the seed is being fixed during the compilation, but I can't figure out how to change that.

If anyone has a solution I would appreciate your help. David

0 Comments

David

2 Answers

Answer by Kaustubha Govind on 14 Feb 2013
Accepted answer

It looks like the 'Seed' parameter is a non-tunable parameter, so I'm not sure how you would do this, other than manually modify the code and add a wrapper around it to get the Seed value as a command-line parameter, or perhaps compute it based on the system clock or something. (If it were a tunable parameter, you could just declare it as an ImportedExtern parameter that your wrapper code could then define)

However, in general, if you plan to use the generated code in your own application, you would probably generate a DLL from the model, instead of an executable. In case of a DLL, it is initialized once, and then executed multiple times before termination. In this case, since the seed is initialized only once, a different random value should be obtained for each execution.

3 Comments

Azzi Abdelmalek on 14 Feb 2013

If the seed is constant, Then he will get, each simulation, the same sequence

David on 14 Feb 2013

Hi Kaustubha, thank you for your answer. It is too bad the seeds get fixed. The plan is to generate an executable as a standalone application, so I think I will try hacking the code.

I guess I could also write an sfunction to give me random numbers. Either way it would appear that I'm headed to the unfamiliar world of C.

David on 15 Feb 2013

I wrote an sfunction to solve the issue. Now when I compile the Simulink model containing this sfunction, each time I run the executable the output is different. I'm posting the code here in case anyone has the same issue; hopefully this will be of some help. Forgive the formatting, the tool doesn't seem to handle c-code very well.

--------------------------------------------------------------

/* Define S-function a name */

#define S_FUNCTION_NAME cfun_rand_gaus

#define S_FUNCTION_LEVEL 2

/* Include definition files */

#include "simstruc.h"

#include stdlib.h

#include math.h

#include<time.h>

/* Function: mdlInitializeSizes ======================================================= */

static void mdlInitializeSizes(SimStruct *S) {

ssSetNumSFcnParams(S, 0);

if (ssGetNumSFcnParams(S) != ssGetSFcnParamsCount(S)) {

return; /* Parameter mismatch will be reported by Simulink */

}

    ssSetNumContStates(S, 0);
    ssSetNumDiscStates(S, 0);

if (!ssSetNumInputPorts(S, 2)) return;

    ssSetInputPortWidth(S, 0, 1);

ssSetInputPortDirectFeedThrough(S, 0, 1);

    ssSetInputPortWidth(S, 1, 1);

ssSetInputPortDirectFeedThrough(S, 1, 1);

if (!ssSetNumOutputPorts(S,1)) return; ssSetOutputPortWidth(S, 0, 1);

    ssSetNumPWork(S,1);
    ssSetNumSampleTimes(S, 1);

/* Take care when specifying exception free code - see sfuntmpl.doc */

ssSetOptions(S, SS_OPTION_EXCEPTION_FREE_CODE);

}

static void mdlInitializeSampleTimes(SimStruct *S)

{ ssSetSampleTime(S, 0, INHERITED_SAMPLE_TIME);

ssSetOffsetTime(S, 0, 0.0);

}

#define MDL_START /* Change to #undef to remove function */

#if defined(MDL_START)

/* Function: mdlStart =======================================================
 */
static void mdlStart(SimStruct *S)
{

srand ( time(NULL) );

}

#endif /* MDL_START */

/* Function: mdlOutputs ======================================================= */

static void mdlOutputs(SimStruct *S, int_T tid)

{

InputRealPtrsType xmean = ssGetInputPortRealSignalPtrs(S,0);

InputRealPtrsType xmu = ssGetInputPortRealSignalPtrs(S,1);

real_T *val_rand = ssGetOutputPortRealSignal(S,0);

/* Gaussian RNG based on the method discussed in Knuth and due originally to Marsaglia */

/* -reference code found here: http://c-faq.com/lib/gaussian.html*/

static double v1, v2, rsq;

static int phase = 0;

double gset;

if(phase == 0) {

do {

double ran1 = (double)rand() / RAND_MAX;

double ran2 = (double)rand() / RAND_MAX;

v1 = 2 * ran1 - 1;

v2 = 2 * ran2 - 1;

rsq = v1 * v1 + v2 * v2;

} while(rsq >= 1 rsq == 0);

gset = v1 * sqrt(-2 * log(rsq) / rsq);

} else {

gset = v2 * sqrt(-2 * log(rsq) / rsq);

}

phase = 1 - phase;

val_rand[0] = *xmean[0] + *xmu[0] * gset;

}

/*=============================*

 * Required S-function trailer *
 *=============================*/

static void mdlTerminate(SimStruct *S){}

#ifdef MATLAB_MEX_FILE /* Is this file being compiled as a MEX-file? */

#include "simulink.c" /* MEX-file interface mechanism */

#else

#include "cg_sfun.h" /* Code generation registration function */

#endif

Kaustubha Govind
Answer by Azzi Abdelmalek on 14 Feb 2013
Edited by Azzi Abdelmalek on 14 Feb 2013

You create a mat file fic_seed.mat

seedv=1:300
save fic_seed seedv

In model properties-callbacks-Init Fcn write this code

v=load('fic')
v=v.v;
val=v(1);
v(1)=[];
save fic v
set_param('yoursimulinkmodelname/Random Number','seed',num2str(val))

Random Number is the name of your random block, Check if it's the same name in your simulink model.

1 Comment

Kaustubha Govind on 14 Feb 2013

Azzi: Since David wants to do this in the generated code, the InitFcn callback won't help unfortunately, since it is only called within the Simulink environment.

Azzi Abdelmalek

Contact us