So I'm trying to create a little something and I have looked all over the place looking for ways of generating a random number. However no matter where I test my code, it results in a non-random number. Here is an example I wrote up.
local lowdrops = {"Wooden Sword","Wooden Bow","Ion Thruster Machine Gun Blaster"}
local meddrops = {}
local highdrops = {}
function randomLoot(lootCategory)
if lootCategory == low then
print(lowdrops[math.random(3)])
end
if lootCategory == medium then
end
if lootCategory == high then
end
end
randomLoot(low)
Wherever I test my code I get the same result. For example when I test the code here http://www.lua.org/cgi-bin/demo it always ends up with the "Ion Thruster Machine Gun Blaster" and doesen't randomize. For that matter testing simply
random = math.random (10)
print(random)
gives me 9, is there something i'm missing?
You need to run math.randomseed() once before using math.random(), like this:
math.randomseed(os.time())
One possible problem is that the first number may not be so "randomized" in some platforms. So a better solution is to pop some random number before using them for real:
math.randomseed(os.time())
math.random(); math.random(); math.random()
Reference: Lua Math Library
Related
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
I am relatively new to Modelica (Dymola-environment) and I am getting very desperate/upset that I cannot solve such a simple problem as a random number generation in Modelica and I hope that you can help me out.
The simple function random produces a random number between 0 and 1 with an input seed seedIn[3] and produces the output seed seedOut[3] for the next time step or event. The call
(z,seedOut) = random(seedIn);
works perfectly fine.
The problem is that I cannot find a way in Modelica to compute this assignment over time by using the seedOut[3] as the next seedIn[3], which is very frustrating.
My simple program looks like this:
*model Randomgenerator
Real z;
Integer seedIn[3]( start={1,23,131},fixed=true), seedOut[3];
equation
(z,seedOut) = random(seedIn);
algorithm
seedIn := seedOut;
end Randomgenerator;*
I have tried nearly all possibilities with algorithm assignments, initial conditions and equations but none of them works. I just simply want to use seedOut in the next time step. One problem seems to be that when entering into the algorithm section, neither the initial conditions nor the values from the equation section are used.
Using the 'sample' and 'reinit' functions the code below will calculate a new random number at the frequency specified in 'sample'. Note the way of defining the "start value" of seedIn.
model Randomgenerator
Real seedIn[3] = {1,23,131};
Real z;
Real[3] seedOut;
equation
(z,seedOut) = random(seedIn);
when sample(1,1) then
reinit(seedIn,pre(seedOut));
end when;
end Randomgenerator;
The 'pre' function allows the use of the previous value of the variable. If this was not used, the output 'z' would have returned a constant value. Two things regarding the 'reinint' function, it requires use of 'when' and requires 'Real' variables/expressions hence seedIn and seedOut are now defined as 'Real'.
The simple "random" generator I used was:
function random
input Real[3] seedIn;
output Real z;
output Real[3] seedOut;
algorithm
seedOut[1] :=seedIn[1] + 1;
seedOut[2] :=seedIn[2] + 5;
seedOut[3] :=seedIn[3] + 10;
z :=(0.1*seedIn[1] + 0.2*seedIn[2] + 0.3*seedIn[3])/(0.5*sum(seedIn));
end random;
Surely there are other ways depending on the application to perform this operation. At least this will give you something to start with. Hope it helps.
Alright, someone must know easier ways to do this than me.
I'm trying to write a random number generator using a fairly common formula.
--Random Number Generator
local X0=os.time()
local A1=710425941047
local B1=813633012810
local M1=711719770602
local X1=(((A1*X0)+B1)%M1)
local X2=(((A1*X1)+B1)%M1) --then I basically take the vaiable X1 and feed
--it back into itself.
print(X2)
local X3=(((A1*X2)+B1)%M1)
print(X3)
local X4=(((A1*X3)+B1)%M1)
print(X4)
local X5=(((A1*X4)+B1)%M1)
print(X5)
local X6=(((A1*X5)+B1)%M1)
print(X6)
local X7=(((A1*X6)+B1)%M1)
print(X7)
Etc Etc.
Does anybody know a faster way to do this?
I would love to be able to fit it into something along the lines of a:
for i=1,Number do
local X[loop count]=(((A1*X[Loop count-1])+B1)%M1)
math.randomseed(X[loop count])
local roll=math.random(1,20)
print("You rolled a "..roll)
end
io.read()
Type of string.
I'm using it to generate random numbers for pieces of track I'm making in a tabletop game.
Example hunk of code:
if trackclass == "S" then
for i=1,S do --Stated earlier that S=25
local roll=math.random(1,5)
local SP=math.random(1,3)
local Count= roll
if Count == 1 then
local Track = "Straightaway"
p(Track.." Of SP "..SP)
else
end
if Count == 2 then
local Track = "Curve"
p(Track.." of SP "..SP)
else
end
if Count == 3 then
local Track = "Hill"
p(Track.." of SP "..SP)
else
end
if Count == 4 then
local Track = "Water"
p(Track.." of SP "..SP)
else
end
if Count == 5 then
local Track = "Jump"
p(Track.." of SP "..SP)
else
end
end
end
Unfortunately this seems to generate a pretty poor set of random number distribution when I use it and I would really like it to work out better. Any possible assistance in fleshing out the variable loop cycle would be greatly appreciated.
Even something like a call so that every time math.random() is called, it adds one to the X[loop count]] so that every generated number is actually a better pseudo-random number distribution.
Please forgive my semi-rambling. My mind is not necessarily thinking in order right now.
Does anybody know a faster way to do this?
Each XN in the expression is always the previous X, so just restructure the code to use the previous X rather than creating new ones:
local X = os.time()
local A1 = 710425941047
local B1 = 813633012810
local M1 = 711719770602
function myrandomseed(val)
X = val
end
function myrandom()
X = (A1 * X + B1) % M1
return X
end
Now you can call myrandom to your heart's content:
for i=1,100 do
print(myrandom())
end
Another way of packaging it, to avoid static scope, would be generating random number generators as closures, which bind to their state variables:
function getrandom(seed)
local X = seed or os.time()
local A1 = 710425941047
local B1 = 813633012810
local M1 = 711719770602
return function()
X = (A1 * X + B1) % M1
return X
end
end
Now you call getrandom to get a random number generator for a given seed:
local rand = getrandom()
for i=1,100 do
print(rand())
end
I would love to be able to fit it into something along the lines of a:
math.randomseed(X[loop count])
local roll=math.random(1,20)
If you're calling randomseed every time you call random, you're not using Lua's (i.e. C's) random number generator at all. You can see why this is true by looking at myrandomseed above. Why are you funneling your numbers through Lua's random in the first place? Why not just use math.random and be done with it.
Just make to sure to call math.randomseed once rather than every time you call math.random and you'll be fine.
I'm using it to generate random numbers for pieces of track I'm making in a tabletop game. Example hunk of code:
When you see tons of nearly identical code, you should refactor it. When you see variables names like foo1, foo2, etc. you're either naming variables poorly or should be using a list. In your case you have a bunch of branches Count == 1, Count == 2, etc. when we could be using a list. For instance, this does the same thing as your code:
local trackTypes = { 'Straightaway', 'Curve', 'Hill', 'Water', 'Jump' }
for i=1,S do
local trackTypeIndex = math.random(1, #trackTypes)
local SP = math.random(1, 3)
p(trackTypes[trackTypeIndex]..' of SP '..SP)
end
Note that you can probably guess what trackTypes is just by reading the variable name. I have no idea what S and SP are. They are probably not good names.
In Ruby, I need to draw from an exponential distribution with mean m. Please show me how to do it quickly and efficiently. Eg. let's have:
m = 4.2
def exponential_distribution
rand( m * 2 )
end
But of course, this code is wrong, and also, it only returns whole number results. I'm already tired today, please hint me towards a good solution.
If you want to do it from scratch you can use inversion.
def exponential(mean)
-mean * Math.log(rand) if mean > 0
end
If you want to parameterize it with rate lambda, the mean and rate are inverses of each other. Divide by -lambda rather than multiplying by -mean.
Technically it should be log(1.0 - rand), but since 1.0 - rand has a uniform distribution you can save one arithmetic operation by just using rand.
How about using the distribution gem? Here's an example:
require 'distribution'
mean = 4.2
lambda = mean**-1
# generate a rng with exponential distribution
rng = Distribution::Exponential.rng(lambda)
# sample a value
sample = rng.call
If you need to change the value of lambda very often it might be useful to use the p_value method directly. A good sample can be found in the source code for Distribution::Exponential#rng, which basically just uses p_value internally. Here's an example of how to do it:
require 'distribution'
# use the same rng for each call
rng = Random
1.step(5, 0.1) do |mean|
lambda = mean**-1
# sample a value
sample = Distribution::Exponential.p_value(rng.rand, lambda)
end
I have this program that I am working on that is supposed to find the sum of the first 1000 prime numbers. Currently all I am concerned with is making sure that the program is finding the first 1000 prime numbers, I will add the functionality for adding them later. Here is what I have:
#!/usr/bin/ruby
def prime(num)
is_prime = true
for i in 2..Math.sqrt(num)
if (num % i) == 0
is_prime = false
else
is_prime = true
end
end
return is_prime
end
i = 2
number_of_primes = 0
while number_of_primes < 1000
prime = prime(i)
if prime == true
number_of_primes++
end
i++
end
When i try to run the program I get the following feedback:
sumOfPrimes.rb:32: syntax error, unexpected keyword_end
sumOfPrimes.rb:34: syntax error, unexpected keyword_end
what gives? Any direction is appreciated.
Ruby doesn't have ++ operator, you need to do += 1
number_of_primes += 1
Unasked for, but a few pieces of advice if you're interested:
One of the cool things about Ruby is that question marks are legal in method names. As such you'll often find that 'predicate' methods (methods that test something and return true or false) end with a question mark, like this: odd?. Your prime method is a perfect candidate for this, so we can rename it prime?.
You use a local variable, is_prime, to hold whether you have found a factor of the number you're testing yet - this is the kind of thing you'd expect to do in an imperative language such as java or C - but Ruby has all sorts of cool features from functional programming that you will gain great power and expressiveness by learning. If you haven't come across them before, you may need to google what a block is and how the syntax works, but for this purpose you can just think of it as a way to get some code run on every item of a collection. It can be used with a variety of cool methods, and one of them is perfectly suited to your purpose: none?, which returns true if no items in the collection it is called on, when passed to the code block you give, return true. So your prime? method can be rewritten like this:
def prime? num
(2..Math.sqrt(num)).none? { |x| num % x == 0 }
end
Apart from being shorter, the advantage of not needing to use local variables like is_prime is that you give yourself fewer opportunities to introduce bugs - if for example you think the contents of is_prime is one thing but it's actually another. It's also, if you look carefully, a lot closer to the actual mathematical definition of a prime number. So by cutting out the unnecessary code you can get closer to exposing the 'meaning' of what you're writing.
As far as getting the first 1000 primes goes, infinite streams are a really cool way to do this but are probably a bit complex to explain here - definitely google if you're interested as they really are amazing! But just out of interest, here's a simple way you could do it using just recursion and no local variables (remember local variables are the devil!):
def first_n_primes(i = 2, primes = [], n)
if primes.count == n then primes
elsif prime? i then first_n_primes(i + 1, primes + [i], n)
else first_n_primes(i + 1, primes, n)
end
end
And as far as summing them up goes all I'll say is have a search for a ruby method called inject - also called reduce. It might be a bit brain-bending at first if you haven't come across the concept before but it's well worth learning! Very cool and very powerful.
Have fun!