From a8b4c615a6531c9303bdcfcb6a4002265d32d67b Mon Sep 17 00:00:00 2001 From: rob tillaart Date: Thu, 23 Dec 2021 20:43:00 +0100 Subject: [PATCH] 0.1.4 Prandom --- libraries/Prandom/.arduino-ci.yml | 10 +++- .../.github/workflows/arduino_test_runner.yml | 10 +++- libraries/Prandom/LICENSE | 2 +- libraries/Prandom/Prandom.cpp | 59 ++++++++++--------- libraries/Prandom/Prandom.h | 22 ++++--- libraries/Prandom/README.md | 19 ++++-- .../test_random_timing/test_random_timing.ino | 23 +++++++- .../examples/test_range/test_range.ino | 24 ++++++-- libraries/Prandom/keywords.txt | 9 ++- libraries/Prandom/library.json | 7 ++- libraries/Prandom/library.properties | 2 +- libraries/Prandom/test/unit_test_001.cpp | 7 ++- 12 files changed, 131 insertions(+), 63 deletions(-) diff --git a/libraries/Prandom/.arduino-ci.yml b/libraries/Prandom/.arduino-ci.yml index ff5659b9..cecf5850 100644 --- a/libraries/Prandom/.arduino-ci.yml +++ b/libraries/Prandom/.arduino-ci.yml @@ -2,6 +2,10 @@ compile: # Choosing to run compilation tests on 2 different Arduino platforms platforms: - uno - - leonardo - - due - - zero + # - due + # - zero + # - leonardo + - m4 + - esp32 + # - esp8266 + # - mega2560 diff --git a/libraries/Prandom/.github/workflows/arduino_test_runner.yml b/libraries/Prandom/.github/workflows/arduino_test_runner.yml index 476456bb..096b975b 100644 --- a/libraries/Prandom/.github/workflows/arduino_test_runner.yml +++ b/libraries/Prandom/.github/workflows/arduino_test_runner.yml @@ -4,10 +4,14 @@ name: Arduino CI on: [push, pull_request] jobs: - arduino_ci: + runTest: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - uses: Arduino-CI/action@master - # Arduino-CI/action@v0.1.1 + - uses: ruby/setup-ruby@v1 + with: + ruby-version: 2.6 + - run: | + gem install arduino_ci + arduino_ci.rb diff --git a/libraries/Prandom/LICENSE b/libraries/Prandom/LICENSE index 8eba944a..c3d6b3da 100644 --- a/libraries/Prandom/LICENSE +++ b/libraries/Prandom/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2020-2021 Rob Tillaart +Copyright (c) 2020-2022 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 diff --git a/libraries/Prandom/Prandom.cpp b/libraries/Prandom/Prandom.cpp index f1534116..4d1adcb8 100644 --- a/libraries/Prandom/Prandom.cpp +++ b/libraries/Prandom/Prandom.cpp @@ -1,7 +1,7 @@ // // FILE: Prandom.cpp // AUTHOR: Rob dot Tillaart at gmail dot com -// VERSION: 0.1.3 +// VERSION: 0.1.4 // PURPOSE: Arduino library for random number generation with Python random interface // URL: https://github.com/RobTillaart/Prandom // @@ -10,10 +10,11 @@ // https://docs.python.org/3/library/random.html // 0.1.1 renamed all to Prandom // 0.1.2 2020-06-19 fix library.json -// 0.1.3 2021-01-06 arduino-CI + unit test - -// code based upon Python implementation although some small -// optimizations and tweaks were needed to get it working. +// 0.1.3 2021-01-06 Arduino-CI + unit test +// 0.1.4 2021-12-23 update library.json, readme, license, minor edits +// +// code based upon Python implementation although some small +// optimizations and tweaks were needed to get it working. #include "Prandom.h" @@ -40,7 +41,7 @@ void Prandom::seed() void Prandom::seed(uint32_t s, uint32_t t) { - // set marsaglia constants, prevent 0 as value + // set Marsaglia constants, prevent 0 as value if (s == 0) s = 1; if (t == 0) t = 2; _m_w = s; @@ -70,8 +71,8 @@ uint32_t Prandom::randrange(uint32_t start, uint32_t stop, uint32_t 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. +// note: not all possible (0xFFFFFFFF) values are used +// function has an uniform distribution. float Prandom::random(const float top) { if (top == 0) return 0; @@ -108,7 +109,7 @@ float Prandom::triangular(float lo, float hi, float mid) 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); + const float NV_MAGICCONST = 2 * exp(-0.5) / sqrt(2.0); float u1, u2, z; while (true) @@ -129,7 +130,7 @@ float Prandom::lognormvariate(float mu, float sigma) } -// implemented slightly differently +// implemented slightly differently float Prandom::gauss(float mu, float sigma) { static bool generate = false; @@ -176,22 +177,22 @@ float Prandom::gammavariate(float alpha, float beta) float u1, u2, v, x, z, r; while (true) - { + { u1 = random(); - if (u1 < 1e-7) continue; + 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; - } - } + (r >= log(z)) ) + { + return x * beta; + } + } } else if (alpha == 1.0) { @@ -203,22 +204,22 @@ float Prandom::gammavariate(float alpha, float beta) float u, b, p, x, u1; while (true) - { + { u = random(); - b = (EULER + alpha)/ EULER; + 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; - } + { + if (u1 <= pow(x, (alpha - 1.0))) break; + } else - { - if (u1 <= exp(-x)) break; - } - } + { + if (u1 <= exp(-x)) break; + } + } return x * beta; } } @@ -242,7 +243,7 @@ float Prandom::paretovariate(float alpha) float Prandom::weibullvariate(float alpha, float beta) { float u = 1 - random(); - return alpha * pow(-log(u), 1.0/beta); + return alpha * pow(-log(u), 1.0 / beta); } @@ -309,4 +310,6 @@ uint32_t Prandom::__random() return (_m_z << 16) + _m_w; /* 32-bit result */ } + // -- END OF FILE -- + diff --git a/libraries/Prandom/Prandom.h b/libraries/Prandom/Prandom.h index 29ffea56..81a59388 100644 --- a/libraries/Prandom/Prandom.h +++ b/libraries/Prandom/Prandom.h @@ -2,18 +2,19 @@ // // FILE: Prandom.h // AUTHOR: Rob dot Tillaart at gmail dot com -// VERSION: 0.1.3 +// VERSION: 0.1.4 // 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/Prandom // https://docs.python.org/3/library/random.html // https://www.pcg-random.org/ -// + #include "Arduino.h" -#define PRANDOM_LIB_VERSION (F("0.1.3")) +#define PRANDOM_LIB_VERSION (F("0.1.4")) + class Prandom { @@ -22,9 +23,9 @@ public: Prandom(uint32_t s); void seed(); - void seed(uint32_t s, uint32_t t = 2); // marsaglia need 2 seeds, but 1 will work too + 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); @@ -33,7 +34,7 @@ public: // 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); @@ -47,14 +48,15 @@ public: 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. + // kappa is concentration parameter, 0 -> uniform. float vonmisesvariate(float mu, float kappa = 0); + private: uint32_t _rndTime(); @@ -66,4 +68,6 @@ private: uint32_t __random(); }; + // -- END OF FILE -- + diff --git a/libraries/Prandom/README.md b/libraries/Prandom/README.md index 55475c69..0389f577 100644 --- a/libraries/Prandom/README.md +++ b/libraries/Prandom/README.md @@ -1,19 +1,30 @@ [![Arduino CI](https://github.com/RobTillaart/Prandom/workflows/Arduino%20CI/badge.svg)](https://github.com/marketplace/actions/arduino_ci) +[![Arduino-lint](https://github.com/RobTillaart/Prandom/actions/workflows/arduino-lint.yml/badge.svg)](https://github.com/RobTillaart/Prandom/actions/workflows/arduino-lint.yml) +[![JSON check](https://github.com/RobTillaart/Prandom/actions/workflows/jsoncheck.yml/badge.svg)](https://github.com/RobTillaart/Prandom/actions/workflows/jsoncheck.yml) [![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](https://github.com/RobTillaart/Prandom/blob/master/LICENSE) [![GitHub release](https://img.shields.io/github/release/RobTillaart/Prandom.svg?maxAge=3600)](https://github.com/RobTillaart/Prandom/releases) + # Prandom -Arduino library for random number generation with Python random interface +Arduino library for random number generation with Python random interface. -# Description +## Description See Python Random library - https://docs.python.org/3/library/random.html -# Operation +## Operation + +See examples. + + +## Future + +- follow developments in Python random library. +- improve documentation. +- add more RNG's to choose from. -See examples diff --git a/libraries/Prandom/examples/test_random_timing/test_random_timing.ino b/libraries/Prandom/examples/test_random_timing/test_random_timing.ino index 7d19c967..219d0a4b 100644 --- a/libraries/Prandom/examples/test_random_timing/test_random_timing.ino +++ b/libraries/Prandom/examples/test_random_timing/test_random_timing.ino @@ -1,11 +1,9 @@ // // FILE: test_random_timing.ino // AUTHOR: Rob Tillaart -// VERSION: 0.1.0 // PURPOSE: demo // DATE: 2020-05-13 -// (c) : MIT -// + #include "Prandom.h" @@ -15,6 +13,7 @@ Prandom R; uint32_t start, stop; + void setup() { Serial.begin(115200); @@ -45,6 +44,7 @@ void setup() Serial.println("\nDone..."); } + void loop() {} @@ -64,6 +64,7 @@ void test_randrange_1() Serial.println(__FUNCTION__); } + void test_randrange_2() { uint32_t sum = 0; @@ -80,6 +81,7 @@ void test_randrange_2() Serial.println(__FUNCTION__); } + void test_randrange_3() { uint32_t sum = 0; @@ -96,6 +98,7 @@ void test_randrange_3() Serial.println(__FUNCTION__); } + void test_random_0() { float sum = 0; @@ -112,6 +115,7 @@ void test_random_0() Serial.println(__FUNCTION__); } + void test_random_1() { float sum = 0; @@ -128,6 +132,7 @@ void test_random_1() Serial.println(__FUNCTION__); } + void test_uniform_2() { float sum = 0; @@ -144,6 +149,7 @@ void test_uniform_2() Serial.println(__FUNCTION__); } + void test_triangular_0() { float sum = 0; @@ -160,6 +166,7 @@ void test_triangular_0() Serial.println(__FUNCTION__); } + void test_normalvariate_2() { float sum = 0; @@ -176,6 +183,7 @@ void test_normalvariate_2() Serial.println(__FUNCTION__); } + void test_lognormvariate_2() { float sum = 0; @@ -192,6 +200,7 @@ void test_lognormvariate_2() Serial.println(__FUNCTION__); } + void test_gauss_2() { float sum = 0; @@ -208,6 +217,7 @@ void test_gauss_2() Serial.println(__FUNCTION__); } + void test_expovariate_1() { float sum = 0; @@ -224,6 +234,7 @@ void test_expovariate_1() Serial.println(__FUNCTION__); } + void test_gammavariate_2() { float sum = 0; @@ -240,6 +251,7 @@ void test_gammavariate_2() Serial.println(__FUNCTION__); } + void test_betavariate_2() { float sum = 0; @@ -256,6 +268,7 @@ void test_betavariate_2() Serial.println(__FUNCTION__); } + void test_paretovariate_1() { float sum = 0; @@ -272,6 +285,7 @@ void test_paretovariate_1() Serial.println(__FUNCTION__); } + void test_weibullvariate_2() { float sum = 0; @@ -288,6 +302,7 @@ void test_weibullvariate_2() Serial.println(__FUNCTION__); } + void test_vonmisesvariate_2() { float sum = 0; @@ -304,4 +319,6 @@ void test_vonmisesvariate_2() Serial.println(__FUNCTION__); } + // -- END OF FILE -- + diff --git a/libraries/Prandom/examples/test_range/test_range.ino b/libraries/Prandom/examples/test_range/test_range.ino index 831617ee..fd44f679 100644 --- a/libraries/Prandom/examples/test_range/test_range.ino +++ b/libraries/Prandom/examples/test_range/test_range.ino @@ -1,11 +1,9 @@ // // FILE: test_range.ino // AUTHOR: Rob Tillaart -// VERSION: 0.1.0 // PURPOSE: demo // DATE: 2020-05-13 -// (c) : MIT -// + #include "Prandom.h" @@ -15,6 +13,7 @@ Prandom R; uint32_t start, stop; + void setup() { Serial.begin(115200); @@ -79,6 +78,7 @@ void test_randrange_1() Serial.println(__FUNCTION__); } + void test_randrange_2() { float sum = 0; @@ -108,6 +108,7 @@ void test_randrange_2() Serial.println(__FUNCTION__); } + void test_randrange_3() { float sum = 0; @@ -137,6 +138,7 @@ void test_randrange_3() Serial.println(__FUNCTION__); } + void test_random_0() { float sum = 0; @@ -166,6 +168,7 @@ void test_random_0() Serial.println(__FUNCTION__); } + void test_random_1() { float sum = 0; @@ -195,6 +198,7 @@ void test_random_1() Serial.println(__FUNCTION__); } + void test_uniform_2() { float sum = 0; @@ -224,6 +228,7 @@ void test_uniform_2() Serial.println(__FUNCTION__); } + void test_triangular_0() { float sum = 0; @@ -253,6 +258,7 @@ void test_triangular_0() Serial.println(__FUNCTION__); } + void test_normalvariate_2() { float sum = 0; @@ -282,6 +288,7 @@ void test_normalvariate_2() Serial.println(__FUNCTION__); } + void test_lognormvariate_2() { float sum = 0; @@ -311,6 +318,7 @@ void test_lognormvariate_2() Serial.println(__FUNCTION__); } + void test_gauss_2() { float sum = 0; @@ -340,6 +348,7 @@ void test_gauss_2() Serial.println(__FUNCTION__); } + void test_expovariate_1() { float sum = 0; @@ -369,6 +378,7 @@ void test_expovariate_1() Serial.println(__FUNCTION__); } + void test_gammavariate_2() { float sum = 0; @@ -398,6 +408,7 @@ void test_gammavariate_2() Serial.println(__FUNCTION__); } + void test_betavariate_2() { float sum = 0; @@ -427,6 +438,7 @@ void test_betavariate_2() Serial.println(__FUNCTION__); } + void test_paretovariate_1() { float sum = 0; @@ -456,6 +468,7 @@ void test_paretovariate_1() Serial.println(__FUNCTION__); } + void test_weibullvariate_2() { float sum = 0; @@ -485,6 +498,7 @@ void test_weibullvariate_2() Serial.println(__FUNCTION__); } + void test_vonmisesvariate_2() { float sum = 0; @@ -514,4 +528,6 @@ void test_vonmisesvariate_2() Serial.println(__FUNCTION__); } -// -- END OF FILE -- \ No newline at end of file + +// -- END OF FILE -- + diff --git a/libraries/Prandom/keywords.txt b/libraries/Prandom/keywords.txt index c7b2103d..036cf21e 100644 --- a/libraries/Prandom/keywords.txt +++ b/libraries/Prandom/keywords.txt @@ -1,14 +1,16 @@ -# Syntax Coloring Map For Prandom +# Syntax Colouring Map For Prandom -# Datatypes (KEYWORD1) +# Data types (KEYWORD1) Prandom KEYWORD1 # Methods and Functions (KEYWORD2) Prandom KEYWORD2 seed KEYWORD2 + getrandbits KEYWORD2 randrange KEYWORD2 randint KEYWORD2 + random KEYWORD2 uniform KEYWORD2 triangular KEYWORD2 @@ -20,9 +22,12 @@ gammavariate KEYWORD2 betavariate KEYWORD2 paretovariate KEYWORD2 weibullvariate KEYWORD2 + vonmisesvariate KEYWORD2 + # Instances (KEYWORD2) + # Constants (LITERAL1) PRANDOM_LIB_VERSION LITERAL1 diff --git a/libraries/Prandom/library.json b/libraries/Prandom/library.json index 1fc474fa..2a5480b9 100644 --- a/libraries/Prandom/library.json +++ b/libraries/Prandom/library.json @@ -1,6 +1,6 @@ { "name": "Prandom", - "keywords": "random normal distribution", + "keywords": "random,normal,distribution", "description": "Arduino library for random number generation with Python random interface.", "authors": [ @@ -15,8 +15,9 @@ "type": "git", "url": "https://github.com/RobTillaart/Prandom.git" }, - "version": "0.1.3", + "version": "0.1.4", "license": "MIT", "frameworks": "arduino", - "platforms": "*" + "platforms": "*", + "headers": "Prandom.h" } diff --git a/libraries/Prandom/library.properties b/libraries/Prandom/library.properties index 2ed506bc..818839be 100644 --- a/libraries/Prandom/library.properties +++ b/libraries/Prandom/library.properties @@ -1,5 +1,5 @@ name=Prandom -version=0.1.3 +version=0.1.4 author=Rob Tillaart maintainer=Rob Tillaart sentence=Arduino library for random number generation with Python random interface. diff --git a/libraries/Prandom/test/unit_test_001.cpp b/libraries/Prandom/test/unit_test_001.cpp index 92fb61d8..53146a20 100644 --- a/libraries/Prandom/test/unit_test_001.cpp +++ b/libraries/Prandom/test/unit_test_001.cpp @@ -38,12 +38,15 @@ unittest_setup() { + fprintf(stderr, "PRANDOM_LIB_VERSION: %s\n", (char *) PRANDOM_LIB_VERSION); } + unittest_teardown() { } + /* unittest(test_new_operator) { @@ -57,10 +60,9 @@ unittest(test_new_operator) } */ + unittest(test_constructor) { - fprintf(stderr, "VERSION: %s\n", PRANDOM_LIB_VERSION); - Prandom R; // three seed() calls are possible @@ -79,6 +81,7 @@ unittest(test_constructor) } + unittest_main() // --------