mirror of
https://github.com/RobTillaart/Arduino.git
synced 2024-10-03 18:09:02 -04:00
add Prandom library
This commit is contained in:
parent
ca83bc255a
commit
0c3a354026
21
libraries/Prandom/LICENSE
Normal file
21
libraries/Prandom/LICENSE
Normal file
@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2020 Rob Tillaart
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
287
libraries/Prandom/Prandom.cpp
Normal file
287
libraries/Prandom/Prandom.cpp
Normal file
@ -0,0 +1,287 @@
|
||||
//
|
||||
// FILE: Prandom.cpp
|
||||
// AUTHOR: Rob dot Tillaart at gmail dot com
|
||||
// VERSION: 0.1.1
|
||||
// PURPOSE: Arduino library for random number generation with Python random interface
|
||||
//
|
||||
// HISTORY:
|
||||
// 0.1.0 2020-05-13 complete redo based upon python random interface
|
||||
// https://docs.python.org/3/library/random.html
|
||||
// 0.1.1 renamed all to Prandom
|
||||
|
||||
// code nased upon Python implementation although some small optimizations
|
||||
// and tweaks were needed to get it working.
|
||||
|
||||
#include "Prandom.h"
|
||||
|
||||
Prandom::Prandom()
|
||||
{
|
||||
seed();
|
||||
}
|
||||
|
||||
Prandom::Prandom(uint32_t s)
|
||||
{
|
||||
seed(s);
|
||||
}
|
||||
|
||||
void Prandom::seed()
|
||||
{
|
||||
// no argument ==> time based.
|
||||
seed(_rndTime());
|
||||
}
|
||||
|
||||
void Prandom::seed(uint32_t s, uint32_t t)
|
||||
{
|
||||
// set marsaglia constants, prevent 0 as value
|
||||
if (s == 0) s = 1;
|
||||
if (t == 0) t = 2;
|
||||
_m_w = s;
|
||||
_m_z = t;
|
||||
}
|
||||
|
||||
uint32_t Prandom::getrandbits(uint8_t n)
|
||||
{
|
||||
uint8_t shift = min(31, n - 1);
|
||||
return _rnd(1UL << shift);
|
||||
}
|
||||
|
||||
uint32_t Prandom::randrange(uint32_t stop)
|
||||
{
|
||||
return _rnd(stop);
|
||||
}
|
||||
|
||||
uint32_t Prandom::randrange(uint32_t start, uint32_t stop, uint32_t step)
|
||||
{
|
||||
if (step == 1) return start + _rnd(stop - start);
|
||||
return start + step * _rnd((stop - start + step - 1) / step);
|
||||
}
|
||||
|
||||
// returns value between 0 and top which defaults to 1.0
|
||||
// the parameter does not exist in Python
|
||||
// note: not all possible (0xFFFFFFFF) values are used
|
||||
// function has an uniform distribution.
|
||||
float Prandom::random(const float top)
|
||||
{
|
||||
if (top == 0) return 0;
|
||||
float f = (top * __random()) / 0xFFFFFFFF;
|
||||
return f;
|
||||
}
|
||||
|
||||
float Prandom::uniform(float lo, float hi)
|
||||
{
|
||||
if (lo == hi) return lo;
|
||||
return lo + random(hi - lo);
|
||||
}
|
||||
|
||||
float Prandom::triangular(float lo, float hi, float mid)
|
||||
{
|
||||
if (lo == hi) return lo;
|
||||
float val = random();
|
||||
|
||||
if (val > mid)
|
||||
{
|
||||
val = 1 - val;
|
||||
mid = 1 - mid;
|
||||
float t = hi;
|
||||
hi = lo;
|
||||
lo = t;
|
||||
}
|
||||
return lo + (hi - lo) * sqrt(val * mid);
|
||||
}
|
||||
|
||||
// minor optimization.
|
||||
float Prandom::normalvariate(float mu, float sigma)
|
||||
{
|
||||
// const float NV_MAGICCONST = 4 * exp(-0.5)/sqrt(2.0);
|
||||
const float NV_MAGICCONST = 2 * exp(-0.5)/sqrt(2.0);
|
||||
|
||||
float u1, u2, z;
|
||||
while (true)
|
||||
{
|
||||
u1 = random();
|
||||
u2 = 1 - random();
|
||||
z = NV_MAGICCONST * (u1 - 0.5) / u2 ;
|
||||
// if ((z * z / 4) <= -log(u2)) break;
|
||||
if ((z * z) <= -log(u2)) break;
|
||||
}
|
||||
return z * sigma + mu;
|
||||
}
|
||||
|
||||
float Prandom::lognormvariate(float mu, float sigma)
|
||||
{
|
||||
return exp(normalvariate(mu, sigma));
|
||||
}
|
||||
|
||||
// implemented slightly differently
|
||||
float Prandom::gauss(float mu, float sigma)
|
||||
{
|
||||
static bool generate = false;
|
||||
static float next = 0;
|
||||
float z = 0;
|
||||
|
||||
generate = !generate;
|
||||
if (generate == false)
|
||||
{
|
||||
z = next;
|
||||
}
|
||||
else
|
||||
{
|
||||
float x2pi = random(TWO_PI);
|
||||
float g2rad = sqrt( -2.0 * log(1.0 - random()));
|
||||
z = cos(x2pi) * g2rad;
|
||||
next = sin(x2pi) * g2rad;
|
||||
}
|
||||
return z * sigma + mu;
|
||||
};
|
||||
|
||||
float Prandom::expovariate(float lambda)
|
||||
{
|
||||
return -log(1.0 - random()) / lambda;
|
||||
}
|
||||
|
||||
// alpha & beta > 0
|
||||
float Prandom::gammavariate(float alpha, float beta)
|
||||
{
|
||||
const float LOG4 = log(4);
|
||||
const float SG_MAGICCONST = 1.0 + log(4.5);
|
||||
|
||||
if (alpha > 1.0)
|
||||
{
|
||||
// # Uses R.C.H. Cheng, "The generation of Gamma
|
||||
// # variables with non-integral shape parameters",
|
||||
// # Applied Statistics, (1977), 26, No. 1, p71-74
|
||||
|
||||
float ainv = sqrt(2.0 * alpha - 1.0);
|
||||
float bbb = alpha - LOG4;
|
||||
float ccc = alpha + ainv;
|
||||
|
||||
float u1, u2, v, x, z, r;
|
||||
while (true)
|
||||
{
|
||||
u1 = random();
|
||||
if (u1 < 1e-7) continue;
|
||||
if (u1 > 0.9999999) continue; // needed?
|
||||
|
||||
u2 = 1.0 - random();
|
||||
v = log(u1 / (1.0 - u1)) / ainv;
|
||||
x = alpha * exp(v);
|
||||
z = u1 * u1 * u2;
|
||||
r = bbb + ccc * v - x;
|
||||
if ( ( (r + SG_MAGICCONST - 4.5 * z) >= 0.0) ||
|
||||
(r >= log(z)) )
|
||||
{
|
||||
return x * beta;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (alpha == 1.0)
|
||||
{
|
||||
return -log(1.0 - random()) * beta;
|
||||
}
|
||||
else // alpha in 0..1
|
||||
{
|
||||
// # Uses ALGORITHM GS of Statistical Computing - Kennedy & Gentle
|
||||
|
||||
float u, b, p, x, u1;
|
||||
while (true)
|
||||
{
|
||||
u = random();
|
||||
b = (EULER + alpha)/ EULER;
|
||||
p = b * u;
|
||||
if ( p <= 1.0) x = pow(p, (1.0 / alpha));
|
||||
else x = -log((b - p) / alpha);
|
||||
u1 = random();
|
||||
if (p > 1.0)
|
||||
{
|
||||
if (u1 <= pow(x, (alpha - 1.0))) break;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (u1 <= exp(-x)) break;
|
||||
}
|
||||
}
|
||||
return x * beta;
|
||||
}
|
||||
}
|
||||
|
||||
float Prandom::betavariate(float alpha, float beta)
|
||||
{
|
||||
float y = gammavariate(alpha, 1.0);
|
||||
if (y == 0) return 0.0;
|
||||
return y / (y + gammavariate(beta, 1.0));
|
||||
};
|
||||
|
||||
float Prandom::paretovariate(float alpha)
|
||||
{
|
||||
float u = 1 - random();
|
||||
return pow(u, (-1.0 / alpha));
|
||||
}
|
||||
|
||||
float Prandom::weibullvariate(float alpha, float beta)
|
||||
{
|
||||
float u = 1 - random();
|
||||
return alpha * pow(-log(u), 1.0/beta);
|
||||
}
|
||||
|
||||
float Prandom::vonmisesvariate(float mu, float kappa)
|
||||
{
|
||||
if (kappa <= 1e-6) return TWO_PI * random();
|
||||
|
||||
float s = 0.5 / kappa;
|
||||
float r = s + sqrt(1.0 + s * s);
|
||||
|
||||
float u1, u2, u3, z, d, q, f, theta;
|
||||
|
||||
do
|
||||
{
|
||||
u1 = random();
|
||||
z = cos(PI * u1);
|
||||
d = z / (r + z);
|
||||
u2 = random();
|
||||
} while ( ( u2 >= 1.0 - d * d ) && (u2 > (1.0 - d) * exp(d)) );
|
||||
|
||||
q = 1.0 / r;
|
||||
f = (q + z) / (1.0 + q * z);
|
||||
|
||||
u3 = random();
|
||||
|
||||
if (u3 > 0.5) theta = mu + acos(f);
|
||||
else theta = mu - acos(f);
|
||||
|
||||
while (theta < 0) theta += TWO_PI;
|
||||
while (theta > TWO_PI) theta -= TWO_PI;
|
||||
|
||||
return theta;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PRIVATE
|
||||
//
|
||||
uint32_t Prandom::_rndTime()
|
||||
{
|
||||
return (micros() + (micros() >> 2) ) ^ (millis());
|
||||
}
|
||||
|
||||
// TODO how to guarantee it uniform between 0 .. n-1
|
||||
uint32_t Prandom::_rnd(uint32_t n)
|
||||
{
|
||||
// float formula works fastest but it looses precision for large values of n
|
||||
// as floats have only 23 bit mantissa
|
||||
uint32_t val = __random();
|
||||
if (n > 0x003FFFFF) return val % n; // distribution will fail here
|
||||
return (n * 1.0 * val) / 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
// An example of a simple pseudo-random number generator is the
|
||||
// Multiply-with-carry method invented by George Marsaglia.
|
||||
// two initializers (not null)
|
||||
uint32_t Prandom::__random()
|
||||
{
|
||||
_m_z = 36969L * (_m_z & 65535L) + (_m_z >> 16);
|
||||
_m_w = 18000L * (_m_w & 65535L) + (_m_w >> 16);
|
||||
return (_m_z << 16) + _m_w; /* 32-bit result */
|
||||
}
|
||||
|
||||
// -- END OF FILE --
|
69
libraries/Prandom/Prandom.h
Normal file
69
libraries/Prandom/Prandom.h
Normal file
@ -0,0 +1,69 @@
|
||||
#pragma once
|
||||
//
|
||||
// FILE: Prandom.h
|
||||
// AUTHOR: Rob dot Tillaart at gmail dot com
|
||||
// VERSION: 0.1.1
|
||||
// PURPOSE: Arduino library for random numbers with Python Random interface
|
||||
// The underlying pseudo-random number generator is a
|
||||
// Multiply-with-carry method invented by George Marsaglia.
|
||||
// URL: https://github.com/RobTillaart/random
|
||||
// https://docs.python.org/3/library/random.html
|
||||
// https://www.pcg-random.org/
|
||||
//
|
||||
|
||||
#include "Arduino.h"
|
||||
|
||||
#define PRANDOM_LIB_VERSION "0.1.1"
|
||||
|
||||
class Prandom
|
||||
{
|
||||
public:
|
||||
Prandom();
|
||||
Prandom(uint32_t s);
|
||||
|
||||
void seed();
|
||||
void seed(uint32_t s, uint32_t t = 2); // marsaglia need 2 seeds, but 1 will work too
|
||||
|
||||
//
|
||||
// integer methods
|
||||
//
|
||||
uint32_t getrandbits(uint8_t n);
|
||||
uint32_t randrange(uint32_t stop);
|
||||
uint32_t randrange(uint32_t start, uint32_t stop, uint32_t step = 1);
|
||||
// randint is inclusive end value
|
||||
uint32_t randint(uint32_t start, uint32_t stop) { return randrange(start, stop + 1); };
|
||||
|
||||
//
|
||||
// real distributions
|
||||
//
|
||||
float random(const float top = 1.0);
|
||||
float uniform(float lo, float hi);
|
||||
float triangular(float lo = 0, float hi = 1.0, float mid = 0.5);
|
||||
float normalvariate(float mu = 0, float sigma = 1.0);
|
||||
float lognormvariate(float mu = 0, float sigma = 1.0);
|
||||
float gauss(float mu = 0, float sigma = 1.0);
|
||||
float expovariate(float lambda);
|
||||
float gammavariate(float alpha, float beta);
|
||||
float betavariate(float alpha, float beta);
|
||||
float paretovariate(float alpha);
|
||||
float weibullvariate(float alpha, float beta);
|
||||
|
||||
//
|
||||
// Circular distributions
|
||||
//
|
||||
// mu is mean angle in radians
|
||||
// kappa is concentration param, 0 -> uniform.
|
||||
float vonmisesvariate(float mu, float kappa = 0);
|
||||
|
||||
private:
|
||||
|
||||
uint32_t _rndTime();
|
||||
uint32_t _rnd(uint32_t n);
|
||||
|
||||
// Marsaglia 'constants'
|
||||
uint32_t _m_w = 1;
|
||||
uint32_t _m_z = 2;
|
||||
uint32_t __random();
|
||||
};
|
||||
|
||||
// -- END OF FILE --
|
12
libraries/Prandom/README.md
Normal file
12
libraries/Prandom/README.md
Normal file
@ -0,0 +1,12 @@
|
||||
# Prandom
|
||||
|
||||
Arduino library for random number generation with Python random interface
|
||||
|
||||
# Description
|
||||
|
||||
See Python Random library - https://docs.python.org/3/library/random.html
|
||||
|
||||
# Operation
|
||||
|
||||
See examples
|
||||
|
@ -0,0 +1,307 @@
|
||||
//
|
||||
// FILE: test_random_timing.ino
|
||||
// AUTHOR: Rob Tillaart
|
||||
// VERSION: 0.1.0
|
||||
// PURPOSE: demo
|
||||
// DATE: 2020-05-13
|
||||
// (c) : MIT
|
||||
//
|
||||
|
||||
#include "Prandom.h"
|
||||
|
||||
const int runs = 1000;
|
||||
|
||||
Prandom R;
|
||||
|
||||
uint32_t start, stop;
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
Serial.println(__FILE__);
|
||||
|
||||
Serial.println(F("TIME\tSUM\t\tFunction"));
|
||||
Serial.println(F("========================================"));
|
||||
|
||||
test_randrange_1();
|
||||
test_randrange_2();
|
||||
test_randrange_3();
|
||||
Serial.println();
|
||||
|
||||
test_random_0();
|
||||
test_random_1();
|
||||
test_uniform_2();
|
||||
test_triangular_0();
|
||||
test_normalvariate_2();
|
||||
test_lognormvariate_2();
|
||||
test_gauss_2();
|
||||
test_expovariate_1();
|
||||
test_gammavariate_2();
|
||||
test_betavariate_2();
|
||||
test_paretovariate_1();
|
||||
test_weibullvariate_2();
|
||||
test_vonmisesvariate_2();
|
||||
|
||||
Serial.println("\nDone...");
|
||||
}
|
||||
|
||||
void loop() {}
|
||||
|
||||
|
||||
void test_randrange_1()
|
||||
{
|
||||
uint32_t sum = 0;
|
||||
start = micros();
|
||||
for (int i = 0; i < runs; i++)
|
||||
{
|
||||
sum += R.randrange(0x000FFFFF);
|
||||
}
|
||||
stop = micros();
|
||||
Serial.print(stop - start);
|
||||
Serial.print("\t");
|
||||
Serial.print(sum);
|
||||
Serial.print("\t");
|
||||
Serial.println(__FUNCTION__);
|
||||
}
|
||||
|
||||
void test_randrange_2()
|
||||
{
|
||||
uint32_t sum = 0;
|
||||
start = micros();
|
||||
for (int i = 0; i < runs; i++)
|
||||
{
|
||||
sum += R.randrange(1000, 2000);
|
||||
}
|
||||
stop = micros();
|
||||
Serial.print(stop - start);
|
||||
Serial.print("\t");
|
||||
Serial.print(sum);
|
||||
Serial.print("\t\t");
|
||||
Serial.println(__FUNCTION__);
|
||||
}
|
||||
|
||||
void test_randrange_3()
|
||||
{
|
||||
uint32_t sum = 0;
|
||||
start = micros();
|
||||
for (int i = 0; i < runs; i++)
|
||||
{
|
||||
sum += R.randrange(1000, 2000, 5);
|
||||
}
|
||||
stop = micros();
|
||||
Serial.print(stop - start);
|
||||
Serial.print("\t");
|
||||
Serial.print(sum);
|
||||
Serial.print("\t\t");
|
||||
Serial.println(__FUNCTION__);
|
||||
}
|
||||
|
||||
void test_random_0()
|
||||
{
|
||||
float sum = 0;
|
||||
start = micros();
|
||||
for (int i = 0; i < runs; i++)
|
||||
{
|
||||
sum += R.random();
|
||||
}
|
||||
stop = micros();
|
||||
Serial.print(stop - start);
|
||||
Serial.print("\t");
|
||||
Serial.print(sum, 4);
|
||||
Serial.print("\t");
|
||||
Serial.println(__FUNCTION__);
|
||||
}
|
||||
|
||||
void test_random_1()
|
||||
{
|
||||
float sum = 0;
|
||||
start = micros();
|
||||
for (int i = 0; i < runs; i++)
|
||||
{
|
||||
sum += R.random(4);
|
||||
}
|
||||
stop = micros();
|
||||
Serial.print(stop - start);
|
||||
Serial.print("\t");
|
||||
Serial.print(sum, 4);
|
||||
Serial.print("\t");
|
||||
Serial.println(__FUNCTION__);
|
||||
}
|
||||
|
||||
void test_uniform_2()
|
||||
{
|
||||
float sum = 0;
|
||||
start = micros();
|
||||
for (int i = 0; i < runs; i++)
|
||||
{
|
||||
sum += R.uniform(EULER, PI);
|
||||
}
|
||||
stop = micros();
|
||||
Serial.print(stop - start);
|
||||
Serial.print("\t");
|
||||
Serial.print(sum, 4);
|
||||
Serial.print("\t");
|
||||
Serial.println(__FUNCTION__);
|
||||
}
|
||||
|
||||
void test_triangular_0()
|
||||
{
|
||||
float sum = 0;
|
||||
start = micros();
|
||||
for (int i = 0; i < runs; i++)
|
||||
{
|
||||
sum += R.triangular(EULER, PI, 3);
|
||||
}
|
||||
stop = micros();
|
||||
Serial.print(stop - start);
|
||||
Serial.print("\t");
|
||||
Serial.print(sum, 4);
|
||||
Serial.print("\t");
|
||||
Serial.println(__FUNCTION__);
|
||||
}
|
||||
|
||||
void test_normalvariate_2()
|
||||
{
|
||||
float sum = 0;
|
||||
start = micros();
|
||||
for (int i = 0; i < runs; i++)
|
||||
{
|
||||
sum += R.normalvariate(5, 1);
|
||||
}
|
||||
stop = micros();
|
||||
Serial.print(stop - start);
|
||||
Serial.print("\t");
|
||||
Serial.print(sum, 4);
|
||||
Serial.print("\t");
|
||||
Serial.println(__FUNCTION__);
|
||||
}
|
||||
|
||||
void test_lognormvariate_2()
|
||||
{
|
||||
float sum = 0;
|
||||
start = micros();
|
||||
for (int i = 0; i < runs; i++)
|
||||
{
|
||||
sum += R.lognormvariate(5, 1);
|
||||
}
|
||||
stop = micros();
|
||||
Serial.print(stop - start);
|
||||
Serial.print("\t");
|
||||
Serial.print(sum, 4);
|
||||
Serial.print("\t");
|
||||
Serial.println(__FUNCTION__);
|
||||
}
|
||||
|
||||
void test_gauss_2()
|
||||
{
|
||||
float sum = 0;
|
||||
start = micros();
|
||||
for (int i = 0; i < runs; i++)
|
||||
{
|
||||
sum += R.gauss(5, 1);
|
||||
}
|
||||
stop = micros();
|
||||
Serial.print(stop - start);
|
||||
Serial.print("\t");
|
||||
Serial.print(sum, 4);
|
||||
Serial.print("\t");
|
||||
Serial.println(__FUNCTION__);
|
||||
}
|
||||
|
||||
void test_expovariate_1()
|
||||
{
|
||||
float sum = 0;
|
||||
start = micros();
|
||||
for (int i = 0; i < runs; i++)
|
||||
{
|
||||
sum += R.expovariate(0.15);
|
||||
}
|
||||
stop = micros();
|
||||
Serial.print(stop - start);
|
||||
Serial.print("\t");
|
||||
Serial.print(sum, 4);
|
||||
Serial.print("\t");
|
||||
Serial.println(__FUNCTION__);
|
||||
}
|
||||
|
||||
void test_gammavariate_2()
|
||||
{
|
||||
float sum = 0;
|
||||
start = micros();
|
||||
for (int i = 0; i < runs; i++)
|
||||
{
|
||||
sum += R.gammavariate(200, 1);
|
||||
}
|
||||
stop = micros();
|
||||
Serial.print(stop - start);
|
||||
Serial.print("\t");
|
||||
Serial.print(sum, 4);
|
||||
Serial.print("\t");
|
||||
Serial.println(__FUNCTION__);
|
||||
}
|
||||
|
||||
void test_betavariate_2()
|
||||
{
|
||||
float sum = 0;
|
||||
start = micros();
|
||||
for (int i = 0; i < runs; i++)
|
||||
{
|
||||
sum += R.betavariate(3, 3);
|
||||
}
|
||||
stop = micros();
|
||||
Serial.print(stop - start);
|
||||
Serial.print("\t");
|
||||
Serial.print(sum, 4);
|
||||
Serial.print("\t");
|
||||
Serial.println(__FUNCTION__);
|
||||
}
|
||||
|
||||
void test_paretovariate_1()
|
||||
{
|
||||
float sum = 0;
|
||||
start = micros();
|
||||
for (int i = 0; i < runs; i++)
|
||||
{
|
||||
sum += R.paretovariate(10);
|
||||
}
|
||||
stop = micros();
|
||||
Serial.print(stop - start);
|
||||
Serial.print("\t");
|
||||
Serial.print(sum, 4);
|
||||
Serial.print("\t");
|
||||
Serial.println(__FUNCTION__);
|
||||
}
|
||||
|
||||
void test_weibullvariate_2()
|
||||
{
|
||||
float sum = 0;
|
||||
start = micros();
|
||||
for (int i = 0; i < runs; i++)
|
||||
{
|
||||
sum += R.weibullvariate(PI, 1);
|
||||
}
|
||||
stop = micros();
|
||||
Serial.print(stop - start);
|
||||
Serial.print("\t");
|
||||
Serial.print(sum, 4);
|
||||
Serial.print("\t");
|
||||
Serial.println(__FUNCTION__);
|
||||
}
|
||||
|
||||
void test_vonmisesvariate_2()
|
||||
{
|
||||
float sum = 0;
|
||||
start = micros();
|
||||
for (int i = 0; i < runs; i++)
|
||||
{
|
||||
sum += R.vonmisesvariate(PI / 2, 0);
|
||||
}
|
||||
stop = micros();
|
||||
Serial.print(stop - start);
|
||||
Serial.print("\t");
|
||||
Serial.print(sum, 4);
|
||||
Serial.print("\t");
|
||||
Serial.println(__FUNCTION__);
|
||||
}
|
||||
|
||||
// -- END OF FILE --
|
517
libraries/Prandom/examples/test_range/test_range.ino
Normal file
517
libraries/Prandom/examples/test_range/test_range.ino
Normal file
@ -0,0 +1,517 @@
|
||||
//
|
||||
// FILE: test_range.ino
|
||||
// AUTHOR: Rob Tillaart
|
||||
// VERSION: 0.1.0
|
||||
// PURPOSE: demo
|
||||
// DATE: 2020-05-13
|
||||
// (c) : MIT
|
||||
//
|
||||
|
||||
#include "Prandom.h"
|
||||
|
||||
const int runs = 1000;
|
||||
|
||||
Prandom R;
|
||||
|
||||
uint32_t start, stop;
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
Serial.println(__FILE__);
|
||||
Serial.println();
|
||||
|
||||
Serial.println(F("TIME\tSUM\t\tSSQ\t\tMIN\tMAX\t\tFunction"));
|
||||
for (int i = 0; i < 70; i++) Serial.print('=');
|
||||
Serial.println();
|
||||
|
||||
test_randrange_1();
|
||||
test_randrange_2();
|
||||
test_randrange_3();
|
||||
Serial.println();
|
||||
|
||||
test_random_0();
|
||||
test_random_1();
|
||||
test_uniform_2();
|
||||
test_triangular_0();
|
||||
test_normalvariate_2();
|
||||
test_lognormvariate_2();
|
||||
test_gauss_2();
|
||||
test_expovariate_1();
|
||||
test_gammavariate_2();
|
||||
test_betavariate_2();
|
||||
test_paretovariate_1();
|
||||
test_weibullvariate_2();
|
||||
test_vonmisesvariate_2();
|
||||
|
||||
Serial.println("\nDone...");
|
||||
}
|
||||
|
||||
void loop() {}
|
||||
|
||||
|
||||
void test_randrange_1()
|
||||
{
|
||||
float sum = 0;
|
||||
float sqsum = 0;
|
||||
float _min = 1e20;
|
||||
float _max = -1e20;
|
||||
start = micros();
|
||||
for (int i = 0; i < runs; i++)
|
||||
{
|
||||
float x = R.randrange(100);
|
||||
if (x < _min) _min = x;
|
||||
if (x > _max) _max = x;
|
||||
sum += x;
|
||||
sqsum += x * x;
|
||||
}
|
||||
stop = micros();
|
||||
Serial.print(stop - start);
|
||||
Serial.print("\t");
|
||||
Serial.print(sum);
|
||||
Serial.print("\t");
|
||||
Serial.print(sqsum);
|
||||
Serial.print("\t");
|
||||
Serial.print(_min);
|
||||
Serial.print("\t");
|
||||
Serial.print(_max);
|
||||
Serial.print("\t");
|
||||
Serial.println(__FUNCTION__);
|
||||
}
|
||||
|
||||
void test_randrange_2()
|
||||
{
|
||||
float sum = 0;
|
||||
float sqsum = 0;
|
||||
float _min = 1e20;
|
||||
float _max = -1e20;
|
||||
start = micros();
|
||||
for (int i = 0; i < runs; i++)
|
||||
{
|
||||
float x = R.randrange(100, 200);
|
||||
if (x < _min) _min = x;
|
||||
if (x > _max) _max = x;
|
||||
sum += x;
|
||||
sqsum += x * x;
|
||||
}
|
||||
stop = micros();
|
||||
Serial.print(stop - start);
|
||||
Serial.print("\t");
|
||||
Serial.print(sum);
|
||||
Serial.print("\t");
|
||||
Serial.print(sqsum);
|
||||
Serial.print("\t");
|
||||
Serial.print(_min);
|
||||
Serial.print("\t");
|
||||
Serial.print(_max);
|
||||
Serial.print("\t\t");
|
||||
Serial.println(__FUNCTION__);
|
||||
}
|
||||
|
||||
void test_randrange_3()
|
||||
{
|
||||
float sum = 0;
|
||||
float sqsum = 0;
|
||||
float _min = 1e20;
|
||||
float _max = -1e20;
|
||||
start = micros();
|
||||
for (int i = 0; i < runs; i++)
|
||||
{
|
||||
float x = R.randrange(100, 200, 5);
|
||||
if (x < _min) _min = x;
|
||||
if (x > _max) _max = x;
|
||||
sum += x;
|
||||
sqsum += x * x;
|
||||
}
|
||||
stop = micros();
|
||||
Serial.print(stop - start);
|
||||
Serial.print("\t");
|
||||
Serial.print(sum);
|
||||
Serial.print("\t");
|
||||
Serial.print(sqsum);
|
||||
Serial.print("\t");
|
||||
Serial.print(_min);
|
||||
Serial.print("\t");
|
||||
Serial.print(_max);
|
||||
Serial.print("\t\t");
|
||||
Serial.println(__FUNCTION__);
|
||||
}
|
||||
|
||||
void test_random_0()
|
||||
{
|
||||
float sum = 0;
|
||||
float sqsum = 0;
|
||||
float _min = 1e20;
|
||||
float _max = -1e20;
|
||||
start = micros();
|
||||
for (int i = 0; i < runs; i++)
|
||||
{
|
||||
float x = R.random();
|
||||
if (x < _min) _min = x;
|
||||
if (x > _max) _max = x;
|
||||
sum += x;
|
||||
sqsum += x * x;
|
||||
}
|
||||
stop = micros();
|
||||
Serial.print(stop - start);
|
||||
Serial.print("\t");
|
||||
Serial.print(sum);
|
||||
Serial.print("\t\t");
|
||||
Serial.print(sqsum);
|
||||
Serial.print("\t\t");
|
||||
Serial.print(_min);
|
||||
Serial.print("\t");
|
||||
Serial.print(_max);
|
||||
Serial.print("\t\t");
|
||||
Serial.println(__FUNCTION__);
|
||||
}
|
||||
|
||||
void test_random_1()
|
||||
{
|
||||
float sum = 0;
|
||||
float sqsum = 0;
|
||||
float _min = 1e20;
|
||||
float _max = -1e20;
|
||||
start = micros();
|
||||
for (int i = 0; i < runs; i++)
|
||||
{
|
||||
float x = R.random(4);
|
||||
if (x < _min) _min = x;
|
||||
if (x > _max) _max = x;
|
||||
sum += x;
|
||||
sqsum += x * x;
|
||||
}
|
||||
stop = micros();
|
||||
Serial.print(stop - start);
|
||||
Serial.print("\t");
|
||||
Serial.print(sum);
|
||||
Serial.print("\t\t");
|
||||
Serial.print(sqsum);
|
||||
Serial.print("\t\t");
|
||||
Serial.print(_min);
|
||||
Serial.print("\t");
|
||||
Serial.print(_max);
|
||||
Serial.print("\t\t");
|
||||
Serial.println(__FUNCTION__);
|
||||
}
|
||||
|
||||
void test_uniform_2()
|
||||
{
|
||||
float sum = 0;
|
||||
float sqsum = 0;
|
||||
float _min = 1e20;
|
||||
float _max = -1e20;
|
||||
start = micros();
|
||||
for (int i = 0; i < runs; i++)
|
||||
{
|
||||
float x = R.uniform(EULER, PI);
|
||||
if (x < _min) _min = x;
|
||||
if (x > _max) _max = x;
|
||||
sum += x;
|
||||
sqsum += x * x;
|
||||
}
|
||||
stop = micros();
|
||||
Serial.print(stop - start);
|
||||
Serial.print("\t");
|
||||
Serial.print(sum);
|
||||
Serial.print("\t\t");
|
||||
Serial.print(sqsum);
|
||||
Serial.print("\t\t");
|
||||
Serial.print(_min);
|
||||
Serial.print("\t");
|
||||
Serial.print(_max);
|
||||
Serial.print("\t\t");
|
||||
Serial.println(__FUNCTION__);
|
||||
}
|
||||
|
||||
void test_triangular_0()
|
||||
{
|
||||
float sum = 0;
|
||||
float sqsum = 0;
|
||||
float _min = 1e20;
|
||||
float _max = -1e20;
|
||||
start = micros();
|
||||
for (int i = 0; i < runs; i++)
|
||||
{
|
||||
float x = R.triangular(0, 10, 3);
|
||||
if (x < _min) _min = x;
|
||||
if (x > _max) _max = x;
|
||||
sum += x;
|
||||
sqsum += x * x;
|
||||
}
|
||||
stop = micros();
|
||||
Serial.print(stop - start);
|
||||
Serial.print("\t");
|
||||
Serial.print(sum);
|
||||
Serial.print("\t");
|
||||
Serial.print(sqsum);
|
||||
Serial.print("\t");
|
||||
Serial.print(_min);
|
||||
Serial.print("\t");
|
||||
Serial.print(_max);
|
||||
Serial.print("\t\t");
|
||||
Serial.println(__FUNCTION__);
|
||||
}
|
||||
|
||||
void test_normalvariate_2()
|
||||
{
|
||||
float sum = 0;
|
||||
float sqsum = 0;
|
||||
float _min = 1e20;
|
||||
float _max = -1e20;
|
||||
start = micros();
|
||||
for (int i = 0; i < runs; i++)
|
||||
{
|
||||
float x = R.normalvariate(5, 1);
|
||||
if (x < _min) _min = x;
|
||||
if (x > _max) _max = x;
|
||||
sum += x;
|
||||
sqsum += x * x;
|
||||
}
|
||||
stop = micros();
|
||||
Serial.print(stop - start);
|
||||
Serial.print("\t");
|
||||
Serial.print(sum);
|
||||
Serial.print("\t\t");
|
||||
Serial.print(sqsum);
|
||||
Serial.print("\t");
|
||||
Serial.print(_min);
|
||||
Serial.print("\t");
|
||||
Serial.print(_max);
|
||||
Serial.print("\t\t");
|
||||
Serial.println(__FUNCTION__);
|
||||
}
|
||||
|
||||
void test_lognormvariate_2()
|
||||
{
|
||||
float sum = 0;
|
||||
float sqsum = 0;
|
||||
float _min = 1e20;
|
||||
float _max = -1e20;
|
||||
start = micros();
|
||||
for (int i = 0; i < runs; i++)
|
||||
{
|
||||
float x = R.lognormvariate(5, 1);
|
||||
if (x < _min) _min = x;
|
||||
if (x > _max) _max = x;
|
||||
sum += x;
|
||||
sqsum += x * x;
|
||||
}
|
||||
stop = micros();
|
||||
Serial.print(stop - start);
|
||||
Serial.print("\t");
|
||||
Serial.print(sum);
|
||||
Serial.print("\t");
|
||||
Serial.print(sqsum);
|
||||
Serial.print("\t");
|
||||
Serial.print(_min);
|
||||
Serial.print("\t");
|
||||
Serial.print(_max);
|
||||
Serial.print("\t\t");
|
||||
Serial.println(__FUNCTION__);
|
||||
}
|
||||
|
||||
void test_gauss_2()
|
||||
{
|
||||
float sum = 0;
|
||||
float sqsum = 0;
|
||||
float _min = 1e20;
|
||||
float _max = -1e20;
|
||||
start = micros();
|
||||
for (int i = 0; i < runs; i++)
|
||||
{
|
||||
float x = R.gauss(5, 1);
|
||||
if (x < _min) _min = x;
|
||||
if (x > _max) _max = x;
|
||||
sum += x;
|
||||
sqsum += x * x;
|
||||
}
|
||||
stop = micros();
|
||||
Serial.print(stop - start);
|
||||
Serial.print("\t");
|
||||
Serial.print(sum);
|
||||
Serial.print("\t\t");
|
||||
Serial.print(sqsum);
|
||||
Serial.print("\t");
|
||||
Serial.print(_min);
|
||||
Serial.print("\t");
|
||||
Serial.print(_max);
|
||||
Serial.print("\t\t");
|
||||
Serial.println(__FUNCTION__);
|
||||
}
|
||||
|
||||
void test_expovariate_1()
|
||||
{
|
||||
float sum = 0;
|
||||
float sqsum = 0;
|
||||
float _min = 1e20;
|
||||
float _max = -1e20;
|
||||
start = micros();
|
||||
for (int i = 0; i < runs; i++)
|
||||
{
|
||||
float x = R.expovariate(1.0 / 5);
|
||||
if (x < _min) _min = x;
|
||||
if (x > _max) _max = x;
|
||||
sum += x;
|
||||
sqsum += x * x;
|
||||
}
|
||||
stop = micros();
|
||||
Serial.print(stop - start);
|
||||
Serial.print("\t");
|
||||
Serial.print(sum);
|
||||
Serial.print("\t\t");
|
||||
Serial.print(sqsum);
|
||||
Serial.print("\t");
|
||||
Serial.print(_min);
|
||||
Serial.print("\t");
|
||||
Serial.print(_max);
|
||||
Serial.print("\t\t");
|
||||
Serial.println(__FUNCTION__);
|
||||
}
|
||||
|
||||
void test_gammavariate_2()
|
||||
{
|
||||
float sum = 0;
|
||||
float sqsum = 0;
|
||||
float _min = 1e20;
|
||||
float _max = -1e20;
|
||||
start = micros();
|
||||
for (int i = 0; i < runs; i++)
|
||||
{
|
||||
float x = R.gammavariate(200, 1);
|
||||
if (x < _min) _min = x;
|
||||
if (x > _max) _max = x;
|
||||
sum += x;
|
||||
sqsum += x * x;
|
||||
}
|
||||
stop = micros();
|
||||
Serial.print(stop - start);
|
||||
Serial.print("\t");
|
||||
Serial.print(sum);
|
||||
Serial.print("\t");
|
||||
Serial.print(sqsum);
|
||||
Serial.print("\t");
|
||||
Serial.print(_min);
|
||||
Serial.print("\t");
|
||||
Serial.print(_max);
|
||||
Serial.print("\t\t");
|
||||
Serial.println(__FUNCTION__);
|
||||
}
|
||||
|
||||
void test_betavariate_2()
|
||||
{
|
||||
float sum = 0;
|
||||
float sqsum = 0;
|
||||
float _min = 1e20;
|
||||
float _max = -1e20;
|
||||
start = micros();
|
||||
for (int i = 0; i < runs; i++)
|
||||
{
|
||||
float x = R.betavariate(3, 3);
|
||||
if (x < _min) _min = x;
|
||||
if (x > _max) _max = x;
|
||||
sum += x;
|
||||
sqsum += x * x;
|
||||
}
|
||||
stop = micros();
|
||||
Serial.print(stop - start);
|
||||
Serial.print("\t");
|
||||
Serial.print(sum);
|
||||
Serial.print("\t\t");
|
||||
Serial.print(sqsum);
|
||||
Serial.print("\t\t");
|
||||
Serial.print(_min);
|
||||
Serial.print("\t");
|
||||
Serial.print(_max);
|
||||
Serial.print("\t\t");
|
||||
Serial.println(__FUNCTION__);
|
||||
}
|
||||
|
||||
void test_paretovariate_1()
|
||||
{
|
||||
float sum = 0;
|
||||
float sqsum = 0;
|
||||
float _min = 1e20;
|
||||
float _max = -1e20;
|
||||
start = micros();
|
||||
for (int i = 0; i < runs; i++)
|
||||
{
|
||||
float x = R.paretovariate(10);
|
||||
if (x < _min) _min = x;
|
||||
if (x > _max) _max = x;
|
||||
sum += x;
|
||||
sqsum += x * x;
|
||||
}
|
||||
stop = micros();
|
||||
Serial.print(stop - start);
|
||||
Serial.print("\t");
|
||||
Serial.print(sum);
|
||||
Serial.print("\t\t");
|
||||
Serial.print(sqsum);
|
||||
Serial.print("\t\t");
|
||||
Serial.print(_min);
|
||||
Serial.print("\t");
|
||||
Serial.print(_max);
|
||||
Serial.print("\t\t");
|
||||
Serial.println(__FUNCTION__);
|
||||
}
|
||||
|
||||
void test_weibullvariate_2()
|
||||
{
|
||||
float sum = 0;
|
||||
float sqsum = 0;
|
||||
float _min = 1e20;
|
||||
float _max = -1e20;
|
||||
start = micros();
|
||||
for (int i = 0; i < runs; i++)
|
||||
{
|
||||
float x = R.weibullvariate(PI, 1);
|
||||
if (x < _min) _min = x;
|
||||
if (x > _max) _max = x;
|
||||
sum += x;
|
||||
sqsum += x * x;
|
||||
}
|
||||
stop = micros();
|
||||
Serial.print(stop - start);
|
||||
Serial.print("\t");
|
||||
Serial.print(sum);
|
||||
Serial.print("\t\t");
|
||||
Serial.print(sqsum);
|
||||
Serial.print("\t");
|
||||
Serial.print(_min);
|
||||
Serial.print("\t");
|
||||
Serial.print(_max);
|
||||
Serial.print("\t\t");
|
||||
Serial.println(__FUNCTION__);
|
||||
}
|
||||
|
||||
void test_vonmisesvariate_2()
|
||||
{
|
||||
float sum = 0;
|
||||
float sqsum = 0;
|
||||
float _min = 1e20;
|
||||
float _max = -1e20;
|
||||
start = micros();
|
||||
for (int i = 0; i < runs; i++)
|
||||
{
|
||||
float x = R.vonmisesvariate(PI / 2, 0);
|
||||
if (x < _min) _min = x;
|
||||
if (x > _max) _max = x;
|
||||
sum += x;
|
||||
sqsum += x * x;
|
||||
}
|
||||
stop = micros();
|
||||
Serial.print(stop - start);
|
||||
Serial.print("\t");
|
||||
Serial.print(sum);
|
||||
Serial.print("\t\t");
|
||||
Serial.print(sqsum);
|
||||
Serial.print("\t");
|
||||
Serial.print(_min);
|
||||
Serial.print("\t");
|
||||
Serial.print(_max);
|
||||
Serial.print("\t\t");
|
||||
Serial.println(__FUNCTION__);
|
||||
}
|
||||
|
||||
// -- END OF FILE --
|
28
libraries/Prandom/keywords.txt
Normal file
28
libraries/Prandom/keywords.txt
Normal file
@ -0,0 +1,28 @@
|
||||
# Syntax Coloring Map For Prandom
|
||||
|
||||
# Datatypes (KEYWORD1)
|
||||
Prandom KEYWORD1
|
||||
|
||||
# Methods and Functions (KEYWORD2)
|
||||
Prandom KEYWORD2
|
||||
seed KEYWORD2
|
||||
getrandbits KEYWORD2
|
||||
randrange KEYWORD2
|
||||
randint KEYWORD2
|
||||
random KEYWORD2
|
||||
uniform KEYWORD2
|
||||
triangular KEYWORD2
|
||||
normalvariate KEYWORD2
|
||||
lognormvariate KEYWORD2
|
||||
gauss KEYWORD2
|
||||
expovariate KEYWORD2
|
||||
gammavariate KEYWORD2
|
||||
betavariate KEYWORD2
|
||||
paretovariate KEYWORD2
|
||||
weibullvariate KEYWORD2
|
||||
vonmisesvariate KEYWORD2
|
||||
|
||||
# Instances (KEYWORD2)
|
||||
|
||||
# Constants (LITERAL1)
|
||||
PRANDOM_LIB_VERSION LITERAL1
|
24
libraries/Prandom/library.json
Normal file
24
libraries/Prandom/library.json
Normal file
@ -0,0 +1,24 @@
|
||||
{
|
||||
"name": "Prandom",
|
||||
"keywords": "random normal distribution",
|
||||
"description": "Arduino library for random number generation with Python random interface.",
|
||||
"authors":
|
||||
[
|
||||
{
|
||||
"name": "Rob Tillaart",
|
||||
"email": "Rob.Tillaart@gmail.com",
|
||||
"maintainer": true
|
||||
}
|
||||
],
|
||||
"repository":
|
||||
{
|
||||
"type": "git",
|
||||
"url": "https://github.com/RobTillaart/Prandom.git"
|
||||
},
|
||||
"version":"0.1.1",
|
||||
"frameworks": "arduino",
|
||||
"platforms": "*",
|
||||
"export": {
|
||||
"include": "Prandom"
|
||||
}
|
||||
}
|
11
libraries/Prandom/library.properties
Normal file
11
libraries/Prandom/library.properties
Normal file
@ -0,0 +1,11 @@
|
||||
name=Prandom
|
||||
version=0.1.1
|
||||
author=Rob Tillaart <rob.tillaart@gmail.com>
|
||||
maintainer=Rob Tillaart <rob.tillaart@gmail.com>
|
||||
sentence=Arduino library for random number generation with Python random interface.
|
||||
paragraph=Supports different distributions
|
||||
category=Data Processing
|
||||
url=https://github.com/RobTillaart/Prandom
|
||||
architectures=*
|
||||
includes=Prandom.h
|
||||
depends=
|
Loading…
Reference in New Issue
Block a user