MATLAB Answers

0

How to create sequence of random numbers in simulink that is non-repeating for every run and supports code generation?

I am trying to create true random numbers in Simulink. I am using the 'rand' and 'normrnd' functions in a MATLAB function blocks.
However, everytime I run my simulation, I see the same sequence of random numbers as the output. I read somewhere to use the command 'coder.extrinsic('rand')' inside the function block. Adding 'coder.extrinsic('rand')' works well during simulation but is not supported for stand-alone code generation.
How to create sequence of random numbers in Simulink that is non-repeating for every run and supports code generation?

Tags

No tags entered yet.

Products


Release

R2017a

1 Answer

Answer by MathWorks Support Team on 19 Jun 2019
 Accepted Answer

There are three possible solutions as listed below :
1) Using the rng('shuffle') command before calling the 'rand' function. Use of rng('shuffle') is only available for standalone code generation in R2018b and later releases.
2) Implement a logic so that the state of the random number generator is initialized based on the system clock each time the application is run, and so the output will contain a unique value each time. You can understand this approach more from this MATLAB Answers post:
Since the MATLAB "clock" command does not help after code generation, you may use the "time" function from the C standard library. The time function from the C standard library can be called to set the unique seed by using "coder.cinclude" and "coder.ceval" as below:
function out = Func_Name (in1, in2)
coder.cinclude('"time.h"')
sd=0;
sd=coder.ceval('time',[]);
rng(sd,'twister');
out = zeros(1,1);
out = normrnd(in1, in2);
Now using these commands, the CodeGen build is smooth and completes without any warnings. However, if you simulate the model or If you run the executable, you will notice that, it keeps returning the same output value for "Func_Name" block for each second.
The core reason for this is that the C function "time" returns time in seconds, and so as a result we keep seeding the same value during the simulation for each second. As a result you will see that the output changes once a second. What is happening is that we are resetting the random number generator with this "constant" seed value every time before we use the "rand" command. This resets the random number generator and outputs same constant value for the second.
The generated code may fail on the hardware. Especially, when random numbers are being generated at a high frequency. The workaround for this behaviour is to seed the random number generator once every time the code is run as a new instance.
The two possible sub-solutions are as given below :
2a) Using a "Clock" block to feed simulation time to the MATLAB function block. Based on this time, we can use a if loop to seed the random number generator only once. You can also use a global variable as a counter instead of the simulation time to seed the random number generator only once.
function out = Func_Name (in1, in2)
coder.cinclude('"time.h"')
if simTime < 0.001
sd=0;
sd=coder.ceval('time',[]);
rng(sd,'twister');
end
out = zeros(1,1);
out = normrnd(in1, in2);
2b) Using a Stateflow chart.
A more elegant way is to use a Stateflow chart. A stateflow chart would easily be able to run the "rng(seed,'twister')" command only once at the start of the run. This way you don't have to add the clock block into the model.
3) Use an S-function.
If you have any external C-code that you have tested for errors, then you can create a S-function. S-function will need a TLC file but do support code generation.

  0 Comments

Sign in to comment.