Generate a random duration - random

I want to know how to generate a random Duration in ada.
There is my code :
time : Duration;
time := 0.8;
How can I add a random value to time between 0.5 and 1.3 ?

The answer is not quite as simple as one might hope. The Ada language provides random number generators for floating point types and for discrete types. The type Duration is a fixed point type.
The following code will generate a random duration in the range of 0.500 seconds to 1.300 seconds (with a random variability to the nearest millisecond).
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Numerics.Discrete_Random;
procedure Main is
Random_Duration : Duration;
type Custom is range 500..1300;
package Rand_Cust is new Ada.Numerics.Discrete_Random(Custom);
use Rand_Cust;
Seed : Generator;
Num : Custom;
begin
-- Create the seed for the random number generator
Reset(Seed);
-- Generate a random integer from 500 to 1300
Num := Random(Seed);
-- Convert Num to a Duration value from 0.5 to 1.3
Random_Duration := Duration(Num) / 1000.0;
-- Output the random duration value
Put_Line(Random_Duration'Image);
end Main;

Related

Setting a range for Random float generation in Ada

Adam.Numerics.Float_Random generates Float values for 0 - 1.0 but i want to generate a Float value between a user defined range. Like Min := 100.0 and Max := 200.0. Something like this:
with Ada.Text_IO, Ada.Integer_Text_IO, Ada.Float_Text_IO;
use Ada.Text_IO, Ada.Integer_Text_IO, Ada.Float_Text_IO;
with Ada.Numerics.Float_Random; use Ada.Numerics.Float_Random;
procedure test1 is
Min, Max, Answer : Float;
subtype Custom is Float range Min .. Max;
package New_Package is new Ada.Numerics.Float_Random(Custom);
use New_Package;
RF : Generator;
begin
Reset(RF);
Get(Min);
Get(Max);
Answer := Random(RF);
Put(Answer, Fore => 1, Aft => 2, Exp => 0);
end test1;
Looks like homework... I usually don't give the answer for such a task :)
First of all, you should get a warning when compiling your code as Min and Max are uninitialized when building your subtype.
To avoid this, the subtype must be declared after values are known.
To do this, declare your subtype inside a declare block.
About the random generation, getting a value inside your range is only a matter of translating and scaling.
In the end, I would do something like this.
with Ada.Float_Text_IO; use Ada.Float_Text_IO;
with Ada.Numerics.Float_Random; use Ada.Numerics.Float_Random;
procedure test1 is
Min, Max : Float;
RF : Generator;
begin
Reset(RF);
Get(Min);
Get(Max);
declare
subtype Custom is Float range Min .. Max;
Answer : Custom;
begin
Answer := (Random(RF) * (Max - Min)) + Min;
Put(Answer, Fore => 1, Aft => 2, Exp => 0);
end;
end test1;
In this particular case, the subtype is quite useless here.

How to map two value ranges in tinygo

I'm using Golang to program a arduino uno with tinygo. I am trying to map two value ranges.
One is an encoder with a range between 0-1000 and the other is tinygo's ADC range between 0-65535. I am reading the ADC range and need to covert it to the range of 0-1000 (encoder).
I have tried several things but the basic issue that I'm running into is data types. The below formula for example equals 0:
var encoderValue uint16 = 35000
float := float64(1000/65535) * float(encoderValue)
1000/65535 is an integer division and will result in 0. It doesn't matter if you convert the result to float64, then it'll be 0.0.
Use floating point constant(s):
var encoderValue uint16 = 35000
x := float64(1000.0/65535) * float64(encoderValue)
fmt.Println(x)
This will output (try it on the Go Playground):
534.0657663843748

Random number within range and a given granularity in Golang

I've written the following code to create a random number between 0.0 and 10.0.
const minRand = 0
const maxRand = 10
v := minRand + rand.Float64()*(maxRand-minRand)
However, I would like to set the granularity to 0.05, so having all the digits as the least significant decimal should not be allowed, only 0 and 5 should be allowed, e.g.:
the value 7.73 is NOT VALID,
the values 7.7 and 7.75 ARE VALID.
How can I produce such numbers in Go?
You can divide with the granularity, get a pseudo random integer and then multiply with the granularity to scale the result down.
const minRand = 8
const maxRand = 10
v := float64(rand.Intn((maxRand-minRand)/0.05))*0.05 + minRand
fmt.Printf("%.2f\n", v)
This will print:
8.05
8.35
8.35
8.95
8.05
9.90
....
If you don't want to get the same sequence every time rand.Seed(time.Now().UTC().UnixNano()).
From the docs
Seed uses the provided seed value to initialize the default Source to a deterministic state. If Seed is not called, the generator behaves as if seeded by Seed(1). Seed values that have the same remainder when divided by 2^31-1 generate the same pseudo-random sequence. Seed, unlike the Rand.Seed method, is safe for concurrent use.
With lower bounds
const minRand = 0
const maxRand = 10
const stepRand = 0.05
v := float64(rand.Intn((maxRand-minRand)/stepRand))*stepRand + minRand
fmt.Printf("%.2f\n", v)

How do I get random numbers in Elm 0.13 without a signal?

I'm making a game where I need to draw random lines on the screen. Now it seems like Random needs a signal to work in 0.13 (and we are forced to work in 0.13). So how do I obtain those random number?
I started from the game skeleton provided at the elm-lang website and got to this:
type UserInput = { space : Bool, keys : [KeyCode] }
type Input = { timeDelta : Float, userInput : UserInput }
userInput : Signal UserInput
userInput = lift2 UserInput Keyboard.space Keyboard.keysDown
framesPerSecond = 30
delta : Signal Float
delta = lift (\t -> t / framesPerSecond) (Time.fps framesPerSecond)
input : Signal Input
input = Signal.sampleOn delta (Signal.lift2 Input delta userInput)
gameState : Signal GameState
gameState = Signal.foldp stepGame defaultGame input
stepGame : Input -> GameState -> GameState
stepGame i g =
if g.state == Start then *Get random floats*
Now in stepGame, I want to draw random lines. The problem is that I can only get random floats by providing a signal in 0.13. I have the Input signal close by the step function, but when I change the header to lets say
stepGame : Signal Input -> GameState -> GameState it doesn't compile. So how do I get a signal in that function to get some random numbers... I can't seem to find the solution, it's driving me crazy.
There are two ways to do this. It really depends on whether the amount of random numbers you need is static or not.
Static number of random numbers
Extend your input with random numbers from Random.floatList:
type Input = { timeDelta : Float, userInput : UserInput, randoms : [Float] }
staticNoOfFloats = 42
input : Signal Input
input = Signal.sampleOn delta (Signal.lift3 Input delta userInput (Random.floatList (always staticNoOfFloats <~ delta)))
Dynamic number of random numbers
Use a community library (also outlined in this SO answer) called generator. You can use a random seed by using Random.range in much the same way as outlined above. The library is a pure pseudo-random number generator based on generating a random number and a new Generator that will produce the next random number.
Why not use Random.floatList in the dynamic case?
Usually if you need a dynamic number of random numbers that number is dependent on the current state of the program. Because that state is captured inside the foldp, where you're also doing your updating based on those random numbers, this makes it impossible to use a "signal function", i.e. something of type Signal a -> Signal b.

Number of bits to represent an integer in VHDL

I have to convert an integer to find how many bits are required to represent that integer.
Let say, integer value is 22. I know 5 bits are required to represent this integer.
Is there any attribute in VHDL to do this?
Important: The result should also be an integer, which should represent number of bits.
There is no VHDL attribute or function, but you can create a function like:
-- Returns number of bits required to represent val in binary vector
function bits_req(val : natural) return natural is
variable res_v : natural; -- Result
variable remain_v : natural; -- Remainder used in iteration
begin
res_v := 0;
remain_v := val;
while remain_v > 0 loop -- Iteration for each bit required
res_v := res_v + 1;
remain_v := remain_v / 2;
end loop;
return res_v;
end function;
However, sometimes a ceil_log2 function is also useful, since that gives the number of required address bits based on entries in a memory map, and ceil_log2(val) = bits_req(val - 1).
Use the math_real library. It's not for synthesis, but works great between the architecture and begin statements.
use ieee.math_real.all;
constant nbits : natural := integer(ceil(log2(real(n))));
I use math_real a lot for in-line generating sin/cos tables... again it's between architecture and begin... again, don't try to use math_real in synthesis.
I've used this in Quartus, ISE, Vivado, Modelsim successfully; it might not be supported by everything out there.

Resources