generate random number in omnet++ ini files without any distribution function - random

how can i generate random number between 0 and 1 without using any distribution function in my ini file. in fact i want to "0.7s" in this code be random:
**.host1.mytest[*].sendInterval = 0.7s
send interval is also configured in the NED file as follow:
volatile double sendInterval #unit("s") = default(1s);

To assign a random value from the range (0, 1) write in omnetpp.ini:
**.host1.mytest[*].sendInterval = uniform(0s, 1s)

Related

How can we put a varying packet error rate in omnet++

Is there a way to put a varying PER(packet error rate) in the omnet.ini file for a single simulation? I know to simulate for different simulations and compare the graph, but I want one simulation which varies PER. Generally, we put the PER in the ini file as in percentage and have a constant PER but I want is varying one between 1% to 50%.
PER = 0.5 #Generally we do like this to show 50% PER
PER= #(0.1 to 0.5) #I need something like this
Hope I am clear.
There are two ways of achieving your goal.
Method 1
In NED declare PER parameter with volatile:
parameters:
volatile double PER;
In omnetpp.ini use a random distribution, for example a uniform distribution:
**.somemodule.PER = uniform(0.01, 0.50)
In C++ code of your module use par("PER") in every place where that value is read.
Thanks to volatile every time that parameter is read, a new random value is chosen. Reference: OMNeT++ Simulation Manual
Method 2
In NED declare two parameters:
parameters:
double minPER;
double maxPER;
In omnetpp.ini set the values of these parameters:
**.somemodule.minPER = 0.01
**.somemodule.maxPER = 0.50
In initialize() of your C++ class read these parameters, e.g.:
minPER = par("minPER");
maxPER = par("maxPER");
In C++ in the place where PER value is necessary generate the current value using a random distribution, for example:
double per = uniform(minPER, maxPER);

How to make a simualtion in verilog have different results everytime if it has random values?

I want to generate a different output of the same code every time I run it as it has random values assigned to some variables. Is there a way to do that, for example seeding using time as in C?
Sample code that has the randomization in it:
class ABC;
rand bit [4 : 0] arr []; // dynamic array
constraint arr_size{
arr.size() >= 2;
arr.size() <= 6;
}
endclass
module constraint_array_randomization();
ABC test_class;
initial begin
test_class = new();
test_class.randomize();
$display("The array has the value = %p ", test_class.arr);
end
endmodule
I this is probably dependent on the tool that is being used. For example xcelium from cadence supports xrun -seed some_seed(Questa has -sv_seed some_seed I think). I am certain all tools support something similar. Look for simulation tool reference/manual/guide/help it may support random seed for every simulation run.
Not sure if this is possible from inside of simulation.
As mentioned in the comments for Questa, -sv_seed random should do the trick.
Usually, having an uncontrolled random seeding at simulation creates repeatability issues. In other words, it would be very difficult to debug a failing case if you do not know the seed. But if you insist, then read the following.
You can mimic the 'c' way of randomizing with time. However, there is no good way in verilog to access system time. Therfore, there is no good way to do time based seeding from within the program.
However as always, there is a work-around available. For example, one can use the $system call to get the system time (is system-dependent). Then the srandom function can be used to set the seed. The following (linux-based) example might work for you (or you can tune it up for your system).
Here the time is provided as unix-time by the date +'%s' command. It writes it into a file and then reads from it as 'int' using $fopen/$fscan.
module constraint_array_randomization();
ABC test_class;
int today ;
initial begin
// get system time
$system("date +'%s' > date_file"); // write date into a file
fh = $fopen("date_file", "r");
void'($fscanf(fh, "%d", today)); // cast to void to avoid warnings
$fclose(fh);
$system("rm -f date_file"); // remove the file
$display("time = %d", today);
test_class = new();
test_class.srandom(today); // seed it
test_class.randomize();
$display("The array has the value = %p ", test_class.arr);
end
endmodule

Omnet ini configuration file - set random destination for each node

I want to set random destinations for an array of 100 nodes in Udp basic app
*.host[*].udpApp[0].destAddresses = "host[${intuniform(0,99)}]"
I need to all source nodes to select a random destination and start sending traffic. But omnet++ is giving error in above statement. Already tried
*.host[*].udpApp[0].destAddresses = "host[${0..99}]" but it is only selecting first node for all nodes for 1 simulation run.
You cannot achieve your goal this way because according to OMNeT++ Simulation Manual in INI file:
Variables are substituted textually, and the result is normally not evaluated as an arithmetic expression.
As a matter of fact, the manipulation with the value of destAddresses is unnecessary, because UDP Basic App does choose the destination address randomly from the set given in destAddresses. Take a look at that method in UdpBasicApp.cc:
L3Address UdpBasicApp::chooseDestAddr()
{
int k = intrand(destAddresses.size());
if (destAddresses[k].isUnspecified() || destAddresses[k].isLinkLocal()) {
L3AddressResolver().tryResolve(destAddressStr[k].c_str(), destAddresses[k]);
}
return destAddresses[k];
}
What you should to do is to add all hosts into destAddresses. For example, assuming that there are five hosts in the network:
*.host[*].udpApp[0].destAddresses = "host[0] host[1] host[2] host[3] host[4]"

Printing Noise Seed of Processing Sketch

There is a function noiseSeed(int) to set the seed for a program, but is there any way to print the seed of a program when it begins?
I am making generative art sketches and it would be more convenient to store just a seed number for a result than an entire image.
You can't get the default random seed value.
Check out Processing's source code (specifically the random() and randomSeed() functions) to see that Processing uses an instance of the Random class to generate random numbers. That class does not have a public way to access its seed value, and even if it did, the internalRandom used by Processing isn't accessible to you anyway.
What you can do is create your own seed value and then store that in your own variable. Something like this:
long seed;
void setup(){
seed = (long)random(1000);
randomSeed(seed);
println("Seed value: " + seed);
}
How you come up with that seed is up to you. Here I'm generating a random seed between 0 and 1000, but in real life it can be any long value.
You could then also input this from the user in order to have repeatable random behavior based on the input value.

Julia: How to modify a column of a matrix that has been saved as a binary file?

I am working with large matrices of data (Nrow x Ncol) that are too large to be stored in memory. Instead, it is standard in my field of work to save the data into a binary file. Due to the nature of the work, I only need to access 1 column of the matrix at a time. I also need to be able to modify a column and then save the updated column back into the binary file. So far I have managed to figure out how to save a matrix as a binary file and how to read 1 'column' of the matrix from the binary file into memory. However, after I edit the contents of a column I cannot figure out how to save that column back into the binary file.
As an example, suppose the data file is a 32-bit identity matrix that has been saved to disk.
Nrow = 500
Ncol = 325
data = eye(Float32,Nrow,Ncol)
stream_data = open("data","w")
write(stream_data,data[:])
close(stream_data)
Reading the entire file from disk and then reshaping back into the matrix is straightforward:
stream_data = open("data","r")
data_matrix = read(stream_data,Float32,Nrow*Ncol)
data_matrix = reshape(data_matrix,Nrow,Ncol)
close(stream_data)
As I said before, the data-matrices I am working with are too large to read into memory and as a result the code written above would normally not be possible to execute. Instead, I need to work with 1 column at a time. The following is a solution to read 1 column (e.g. the 7th column) of the matrix into memory:
icol = 7
stream_data = open("data","r")
position_data = 4*Nrow*(icol-1)
seek(stream_data,position_data)
data_col = read(stream_data,Float32,Nrow)
close(stream_data)
Note that the coefficient '4' in the 'position_data' variable is because I am working with Float32. Also, I don't fully understand what the seek command is doing here, but it seems to be giving me the correct output based on the following tests:
data == data_matrix # true
data[:,7] == data_col # true
For the sake of this problem, lets say I have determined that the column I loaded (i.e. the 7th column) needs to be replaced with zeros:
data_col = zeros(Float32,size(data_col))
The problem now, is to figure out how to save this column back into the binary file without affecting any of the other data. Naturally I intend to use 'write' to perform this task. However, I am not entirely sure how to proceed. I know I need to start by opening up a stream to the data; however I am not sure what 'mode' I need to use: "w", "w+", "a", or "a+"? Here is a failed attempt using "w":
icol = 7
stream_data = open("data","w")
position_data = 4*Nrow*(icol-1)
seek(stream_data,position_data)
write(stream_data,data_col)
close(stream_data)
The original binary file (before my failed attempt to edit the binary file) occupied 650000 bytes on disk. This is consistent with the fact that the matrix is size 500x325 and Float32 numbers occupy 4 bytes (i.e. 4*500*325 = 650000). However, after my attempt to edit the binary file I have observed that the binary file now occupies only 14000 bytes of space. Some quick mental math shows that 14000 bytes corresponds to 7 columns of data (4*500*7 = 14000). A quick check confirms that the binary file has replaced all of the original data with a new matrix with size 500x7, and whose elements are all zeros.
stream_data = open("data","r")
data_new_matrix = read(stream_data,Float32,Nrow*7)
data_new_matrix = reshape(data_new_matrix,Nrow,7)
sum(abs(data_new_matrix)) # 0.0f0
What do I need to do/change in order to only modify only the 7th 'column' in the binary file?
Instead of
icol = 7
stream_data = open("data","w")
position_data = 4*Nrow*(icol-1)
seek(stream_data,position_data)
write(stream_data,data_col)
close(stream_data)
in the OP, write
icol = 7
stream_data = open("data","r+")
position_data = 4*Nrow*(icol-1)
seek(stream_data,position_data)
write(stream_data,data_col)
close(stream_data)
i.e. replace "w" with "r+" and everything works.
The reference to open is http://docs.julialang.org/en/release-0.4/stdlib/io-network/#Base.open and it explains the various modes. Preferably open shouldn't be used with the original somewhat confusing but definitely slower string parameter.
You can use SharedArrays for the need you describe:
data=SharedArray("/some/absolute/path/to/a/file", Float32,(Nrow,Ncols))
# do something with data
data[:,1]=a[:,1].+1
exit()
# restart julia
data=SharedArray("/some/absolute/path/to/a/file", Float32,(Nrow,Ncols))
#show data[1,1]
# prints 1
Now, be mindful that you're supposed to handle synchronisation to read/write from/to this file (if you have async workers) and that you're not supposed to change the size of the array (unless you know what you're doing).

Resources