diff --git a/libraries/statHelpers/CHANGELOG.md b/libraries/statHelpers/CHANGELOG.md index f8652cd3..ce3a4b07 100644 --- a/libraries/statHelpers/CHANGELOG.md +++ b/libraries/statHelpers/CHANGELOG.md @@ -6,10 +6,16 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). +## [0.2.0] - 2024-01-06 +- add **skipFactorial(n, skip);** experimental +- Fix URL in examples +- minor edits + +---- + ## [0.1.8] - 2023-11-22 - update readme.md - ## [0.1.7] - 2023-03-15 - update readme.md - update GitHub actions diff --git a/libraries/statHelpers/LICENSE b/libraries/statHelpers/LICENSE index 60983a2e..35847697 100644 --- a/libraries/statHelpers/LICENSE +++ b/libraries/statHelpers/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2010-2023 Rob Tillaart +Copyright (c) 2010-2024 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/statHelpers/README.md b/libraries/statHelpers/README.md index cf5b69aa..abe13db3 100644 --- a/libraries/statHelpers/README.md +++ b/libraries/statHelpers/README.md @@ -81,18 +81,52 @@ but accuracy is less than the **dfactorial()**, see example. ### SemiFactorial SemiFactorials are like factorials but skipping every other. +SemiFactorials are written as a number with two exclamation marks. + +SemiFactorial are defined for +- **odd** values: n!! == n x (n-2) x (n-4) ... x 1 +- **even** values: n!! == n x (n-2) x (n-4) ... x 2 + +Example 12!! = 12 x 10 x 8 x 6 x 4 x 2 = 46080 - **uint32_t semiFactorial(n)** exact up to 20!! -- **uint64_t semiFactorial64(n)** exact up to 33!! (Print 64 bit integers with my printHelpers) +- **uint64_t semiFactorial64(n)** exact up to 33!! (Print 64 bit integers with printHelpers library) - **double dSemiFactorial(n)** not exact up to 56!! (4 byte) or 300!! (8 byte) -SemiFactorial are defined for -- **odd** values: n x (n-2) x (n-4) ... x 1 -- **even** values: n x (n-2) x (n-4) ... x 2 - Notes: -```n! = n!! x (n-1)!!``` this formula allows to calculate the value of n! indirectly +``` +n! = n!! x (n-1)!! +``` +This formula allows to calculate the value of n! indirectly. + + +### SkipFactorial (experimental) + +- **uint32_t skipFactorial(uint32_t n, uint32_t skip)** +- **uint64_t skipFactorial64(uint32_t n, uint32_t skip)** +- **double dSkipFactorial(uint32_t n, uint32_t skip)** + +SkipFactorials are like factorials and semiFactorials but they skip **skip** numbers. +- **skipFactorial(12, 4)** = 12 x 8 x 4 = 384 +- **skipFactorial(17, 5)** = 17 x 12 x 7 x 2 = 2856 +- **skipFactorial(n, 1)** == **factorial(n)** +- **skipFactorial(n, 2)** == **semiFactorial(n)** + +As the maximum depends on both n and step sizze there is no single maximum for n. +This is similar to combinations and permutations. + +An indicative table of maxima per function call, the larger the skip, the larger the maximum n. +Note that for skip <= 10 n still is an 8 bit number. + +| function | n, 2 | n, 3 | n, 4 | n, 5 | n, 10 | notes | +|:------------------|:-------:|:-------:|:-------:|:-------:|:-------:|:--------| +| skipFactorial | 20 | 27 | 32 | 40 | 69 | max expected smaller than 7 x skip when skip > 10. +| skipFactorial64 | 33 | 45 | 55 | 66 | 115 | max expected smaller than 12 x skip when skip > 10. +| dSkipFactorial | 56 | 77 | 95 | 115 | 200 | float (4 bytes) max expected smaller than 20 x skip when skip > 10. +| dSkipFactorial | 300 | | | | | double (8 bytes) + +Note that for the function the **max / skip** is decreasing when **skip grows**. ### Combinations @@ -184,9 +218,8 @@ See examples - investigate a bigFloat class to do math for permutations and combinations to substantially larger values. - Look for ways to extend the scope -- **skipFactorial(uint32_t n, uint32_t skip)** == n x (n-skip) x (n -skip -skip) ... x S (depends on size of skip) - - e.g. skipFactorial(12, 4) = 12 x 8 x 4. - - skipFactorial(n, 2) == semiFactorial(n); +- fill table for skipFactorial for **double** + #### Wont diff --git a/libraries/statHelpers/examples/bigCombinations/bigCombinations.ino b/libraries/statHelpers/examples/bigCombinations/bigCombinations.ino index 985dd479..b6c4c562 100644 --- a/libraries/statHelpers/examples/bigCombinations/bigCombinations.ino +++ b/libraries/statHelpers/examples/bigCombinations/bigCombinations.ino @@ -18,6 +18,9 @@ void setup() { Serial.begin(115200); Serial.println(__FILE__); + Serial.print("STATHELPERS_LIB_VERSION: "); + Serial.println(STATHELPERS_LIB_VERSION); + Serial.println(); Serial.println("dcombinations(n, k); "); delay(10); @@ -63,7 +66,7 @@ void setup() Serial.print(expo); Serial.println(); } - //Serial.println(); + // Serial.println(); } duration1 = micros() - start; Serial.println(duration1); @@ -78,5 +81,5 @@ void loop() } -// -- END OF FILE -- +// -- END OF FILE -- diff --git a/libraries/statHelpers/examples/bigFactorial/bigFactorial.ino b/libraries/statHelpers/examples/bigFactorial/bigFactorial.ino index ff32b6a2..39dc20a7 100644 --- a/libraries/statHelpers/examples/bigFactorial/bigFactorial.ino +++ b/libraries/statHelpers/examples/bigFactorial/bigFactorial.ino @@ -7,7 +7,7 @@ #include "statHelpers.h" -#include "printHelpers.h" // to print large numbers.... +#include "printHelpers.h" // to print large numbers ... uint32_t start, duration1, duration2, duration3; @@ -17,6 +17,9 @@ void setup() { Serial.begin(115200); Serial.println(__FILE__); + Serial.print("STATHELPERS_LIB_VERSION: "); + Serial.println(STATHELPERS_LIB_VERSION); + Serial.println(); uint32_t m = 10000001; double mant = 0; @@ -77,5 +80,5 @@ void loop() } -// -- END OF FILE -- +// -- END OF FILE -- diff --git a/libraries/statHelpers/examples/bigPermutations/bigPermutations.ino b/libraries/statHelpers/examples/bigPermutations/bigPermutations.ino index 45cd9329..c48a30b8 100644 --- a/libraries/statHelpers/examples/bigPermutations/bigPermutations.ino +++ b/libraries/statHelpers/examples/bigPermutations/bigPermutations.ino @@ -18,6 +18,10 @@ void setup() { Serial.begin(115200); Serial.println(__FILE__); + Serial.print("STATHELPERS_LIB_VERSION: "); + Serial.println(STATHELPERS_LIB_VERSION); + Serial.println(); + /////////////////////////////////////////// @@ -123,7 +127,8 @@ void setup() Serial.println(); */ - // pick 1000 persons from 4294967295 (maxLong) + + // pick 1000 persons from 4294967295 (maxLong) double mant = 0; uint32_t expo = 0; bigPermutations(4294967295, 1000, mant, expo); @@ -141,5 +146,5 @@ void loop() } -// -- END OF FILE -- +// -- END OF FILE -- diff --git a/libraries/statHelpers/examples/combinations/combinations.ino b/libraries/statHelpers/examples/combinations/combinations.ino index f7294901..5ac488b8 100644 --- a/libraries/statHelpers/examples/combinations/combinations.ino +++ b/libraries/statHelpers/examples/combinations/combinations.ino @@ -18,6 +18,10 @@ void setup() { Serial.begin(115200); Serial.println(__FILE__); + Serial.print("STATHELPERS_LIB_VERSION: "); + Serial.println(STATHELPERS_LIB_VERSION); + Serial.println(); + Serial.println("combinations(n, k)"); delay(10); @@ -35,7 +39,7 @@ void setup() // Serial.print(combinations(n, k)); // Serial.println(); } - //Serial.println(); + // Serial.println(); } duration1 = micros() - start; Serial.println(duration1); @@ -57,7 +61,7 @@ void setup() // Serial.print(combinations(n, k)); // Serial.println(); } - //Serial.println(); + // Serial.println(); } duration1 = micros() - start; Serial.println(duration1); @@ -80,7 +84,7 @@ void setup() // Serial.print(print64(combinations64(n, k))); // Serial.println(); } - //Serial.println(); + // Serial.println(); } duration1 = micros() - start; Serial.println(duration1); @@ -101,7 +105,7 @@ void setup() // Serial.print(print64(combinations64(n, k))); // Serial.println(); } - //Serial.println(); + // Serial.println(); } duration1 = micros() - start; Serial.println(duration1); @@ -126,7 +130,7 @@ void setup() // Serial.print(comb(n, k)); // Serial.println(); } - //Serial.println(); + // Serial.println(); } duration1 = micros() - start; Serial.println(duration1); @@ -141,5 +145,5 @@ void loop() } -// -- END OF FILE -- +// -- END OF FILE -- diff --git a/libraries/statHelpers/examples/factorial/factorial.ino b/libraries/statHelpers/examples/factorial/factorial.ino index fe988a1c..ddd2057b 100644 --- a/libraries/statHelpers/examples/factorial/factorial.ino +++ b/libraries/statHelpers/examples/factorial/factorial.ino @@ -7,7 +7,7 @@ #include "statHelpers.h" -#include "printHelpers.h" // to print large numbers.... +#include "printHelpers.h" // to print large numbers.... uint32_t start, duration1, duration2; @@ -17,6 +17,10 @@ void setup() { Serial.begin(115200); Serial.println(__FILE__); + Serial.print("STATHELPERS_LIB_VERSION: "); + Serial.println(STATHELPERS_LIB_VERSION); + Serial.println(); + int m = 35; if (sizeof(double) == 8) m = 175; @@ -94,5 +98,5 @@ void loop() } -// -- END OF FILE -- +// -- END OF FILE -- diff --git a/libraries/statHelpers/examples/factorial_performance/factorial_performance.ino b/libraries/statHelpers/examples/factorial_performance/factorial_performance.ino index 9361fcf4..3092fd55 100644 --- a/libraries/statHelpers/examples/factorial_performance/factorial_performance.ino +++ b/libraries/statHelpers/examples/factorial_performance/factorial_performance.ino @@ -7,7 +7,7 @@ #include "statHelpers.h" -#include "printHelpers.h" // to print large numbers.... +#include "printHelpers.h" // to print large numbers.... uint32_t start, duration1, duration2, duration3; @@ -17,6 +17,10 @@ void setup() { Serial.begin(115200); Serial.println(__FILE__); + Serial.print("STATHELPERS_LIB_VERSION: "); + Serial.println(STATHELPERS_LIB_VERSION); + Serial.println(); + int m = 35; int decimals = 7; @@ -67,5 +71,5 @@ void loop() } -// -- END OF FILE -- +// -- END OF FILE -- diff --git a/libraries/statHelpers/examples/nextPermutation/nextPermutation.ino b/libraries/statHelpers/examples/nextPermutation/nextPermutation.ino index 2a72f8e3..859436df 100644 --- a/libraries/statHelpers/examples/nextPermutation/nextPermutation.ino +++ b/libraries/statHelpers/examples/nextPermutation/nextPermutation.ino @@ -21,7 +21,9 @@ void setup() { Serial.begin(115200); Serial.println(__FILE__); - + Serial.print("STATHELPERS_LIB_VERSION: "); + Serial.println(STATHELPERS_LIB_VERSION); + Serial.println(); Serial.println("120 permutations + print"); do @@ -32,6 +34,7 @@ void setup() } while (nextPermutation(hello, 5)); + //////////////////////////////////////////////////////////////// Serial.println("timing 720 permutations + print"); @@ -52,6 +55,7 @@ void setup() Serial.println(duration1); delay(10); + //////////////////////////////////////////////////////////////// start = micros(); @@ -70,5 +74,5 @@ void loop() } -// -- END OF FILE -- +// -- END OF FILE -- diff --git a/libraries/statHelpers/examples/perm1/perm1.ino b/libraries/statHelpers/examples/perm1/perm1.ino index 7c6bab7f..3f73b12f 100644 --- a/libraries/statHelpers/examples/perm1/perm1.ino +++ b/libraries/statHelpers/examples/perm1/perm1.ino @@ -2,26 +2,29 @@ // FILE: perm1.ino // AUTHOR: Rob Tillaart // DATE: 2010-11-23 -// PUPROSE: demo permutations +// PURPOSE: demo permutations +// URL: https://github.com/RobTillaart/statHelpers // // -// WARNING TAKES LONG -// ======================================================================== -// ESP32 @ 240 MHz string length 8 ==> ~8100 milliseconds => printing!! -// UNO no printing string length 8 ==> ~431 milliseconds -// UNO no printing string length 10 ==> ~38763 milliseconds +// WARNING TAKES LONG +// ======================================================================== +// ESP32 @ 240 MHz string length 8 ==> ~8100 milliseconds => printing!! +// UNO no printing string length 8 ==> ~431 milliseconds +// UNO no printing string length 10 ==> ~38763 milliseconds -char permstring[12] = "0123456789"; // can be made slightly longer +#include "statHelpers.h" + +char permstring[12] = "0123456789"; // can be made slightly longer uint32_t start, stop; void permutate(char * array, uint8_t n) { - if (n == 0) // end reached print the string + if (n == 0) // end reached print the string { - // Serial.println(array); // process permutation + // Serial.println(array); // process permutation return; } @@ -46,7 +49,12 @@ void permutate(char * array, uint8_t n) void setup() { Serial.begin(500000); - + Serial.println(__FILE__); + Serial.print("STATHELPERS_LIB_VERSION: "); + Serial.println(STATHELPERS_LIB_VERSION); + Serial.println(); + + Serial.println("Will take some time.."); Serial.print("perm1 strlen: "); Serial.println(strlen(permstring)); @@ -65,5 +73,4 @@ void loop() } -// -- END OF FILE -- - +// -- END OF FILE -- diff --git a/libraries/statHelpers/examples/permutations/permutations.ino b/libraries/statHelpers/examples/permutations/permutations.ino index a0bc63fa..98a378c2 100644 --- a/libraries/statHelpers/examples/permutations/permutations.ino +++ b/libraries/statHelpers/examples/permutations/permutations.ino @@ -18,6 +18,10 @@ void setup() { Serial.begin(115200); Serial.println(__FILE__); + Serial.print("STATHELPERS_LIB_VERSION: "); + Serial.println(STATHELPERS_LIB_VERSION); + Serial.println(); + Serial.println("permutations(n, k)"); delay(10); @@ -40,6 +44,7 @@ void setup() Serial.println(duration1); Serial.println(); + /////////////////////////////////////////// Serial.println("permutations64(n, k)"); @@ -62,6 +67,7 @@ void setup() Serial.println(duration1); Serial.println(); + /////////////////////////////////////////// Serial.println("dpermutations(n, k) - double can be 4 or 8 bit."); @@ -95,5 +101,5 @@ void loop() } -// -- END OF FILE -- +// -- END OF FILE -- diff --git a/libraries/statHelpers/examples/semiFactorial/semiFactorial.ino b/libraries/statHelpers/examples/semiFactorial/semiFactorial.ino index 9a5a16b5..ce1d9f38 100644 --- a/libraries/statHelpers/examples/semiFactorial/semiFactorial.ino +++ b/libraries/statHelpers/examples/semiFactorial/semiFactorial.ino @@ -7,7 +7,7 @@ #include "statHelpers.h" -#include "printHelpers.h" // to print large numbers.... +#include "printHelpers.h" // to print large numbers.... uint32_t start, duration1, duration2, duration3; @@ -17,6 +17,9 @@ void setup() { Serial.begin(115200); Serial.println(__FILE__); + Serial.print("STATHELPERS_LIB_VERSION: "); + Serial.println(STATHELPERS_LIB_VERSION); + Serial.println(); int m = 60; if (sizeof(double) == 8) m = 301; @@ -39,7 +42,7 @@ void setup() delay(100); uint8_t n = 25; start = micros(); - double d1 = semiFactorial(n); // will fail but indicative + double d1 = semiFactorial(n); // will fail but indicative duration1 = micros() - start; start = micros(); double d2 = semiFactorial64(n); @@ -74,5 +77,5 @@ void loop() } -// -- END OF FILE -- +// -- END OF FILE -- diff --git a/libraries/statHelpers/examples/skipFactorial/skipFactorial.ino b/libraries/statHelpers/examples/skipFactorial/skipFactorial.ino new file mode 100644 index 00000000..b75332d3 --- /dev/null +++ b/libraries/statHelpers/examples/skipFactorial/skipFactorial.ino @@ -0,0 +1,82 @@ +// +// FILE: skipFactorial.ino +// AUTHOR: Rob Tillaart +// PURPOSE: demo +// DATE: 2024-01-06 +// URL: https://github.com/RobTillaart/statHelpers + + +#include "statHelpers.h" +#include "printHelpers.h" // to print large numbers.... + + +uint32_t start, duration1, duration2, duration3; + + +void setup() +{ + Serial.begin(115200); + Serial.println(__FILE__); + Serial.print("STATHELPERS_LIB_VERSION: "); + Serial.println(STATHELPERS_LIB_VERSION); + Serial.println(); + + int m = 300; + int skip = 10; + if (sizeof(double) == 8) m = 301; + + Serial.println("Skip factorial (n, 3) - max reached at n = 27, n = 45, n = 60"); + for (int i = 27; i < m; i++) + { + Serial.print(i); + Serial.print('\t'); + Serial.print(skipFactorial(i, skip)); + Serial.print('\t'); + Serial.print(print64(skipFactorial64(i, skip))); + Serial.print('\t'); + Serial.print(sci(dSkipFactorial(i, skip), 15)); + Serial.println(); + } + Serial.println(); + + Serial.println("PERFORMANCE"); + Serial.println("n\tskipFactorial, skipFactorial64, dSkipFactorial usec\t values"); + delay(100); + uint8_t n = 25; + start = micros(); + double d1 = skipFactorial(n, 3); // will fail but indicative + duration1 = micros() - start; + start = micros(); + double d2 = skipFactorial64(n, 3); + duration2 = micros() - start; + start = micros(); + double d3 = dSkipFactorial(n, 3); + duration3 = micros() - start; + Serial.print(n); + Serial.print('\t'); + Serial.print(duration1); + Serial.print('\t'); + Serial.print('\t'); + Serial.print(duration2); + Serial.print('\t'); + Serial.print('\t'); + Serial.print(duration3); + Serial.println(); + Serial.print('\t'); + Serial.print(sci(d1, 10)); + Serial.print('\t'); + Serial.print(sci(d2, 10)); + Serial.print('\t'); + Serial.print(sci(d3, 10)); + Serial.println(); + + Serial.println("\n Done..."); +} + + +void loop() +{ +} + + +// -- END OF FILE -- diff --git a/libraries/statHelpers/library.json b/libraries/statHelpers/library.json index b6a4c370..6e93fce3 100644 --- a/libraries/statHelpers/library.json +++ b/libraries/statHelpers/library.json @@ -15,7 +15,7 @@ "type": "git", "url": "https://github.com/RobTillaart/statHelpers.git" }, - "version": "0.1.8", + "version": "0.2.0", "license": "MIT", "frameworks": "*", "platforms": "*", diff --git a/libraries/statHelpers/library.properties b/libraries/statHelpers/library.properties index c94196e7..c651fa9b 100644 --- a/libraries/statHelpers/library.properties +++ b/libraries/statHelpers/library.properties @@ -1,5 +1,5 @@ name=statHelpers -version=0.1.8 +version=0.2.0 author=Rob Tillaart maintainer=Rob Tillaart sentence=Arduino library with a number of statistic helper functions. diff --git a/libraries/statHelpers/statHelpers.cpp b/libraries/statHelpers/statHelpers.cpp index 5b2296cc..367e0b15 100644 --- a/libraries/statHelpers/statHelpers.cpp +++ b/libraries/statHelpers/statHelpers.cpp @@ -1,7 +1,7 @@ // // FILE: statHelpers.cpp // AUTHOR: Rob Tillaart -// VERSION: 0.1.8 +// VERSION: 0.2.0 // PURPOSE: Arduino library with a number of statistic helper functions. // DATE: 2020-07-01 // URL: https://github.com/RobTillaart/statHelpers @@ -190,7 +190,7 @@ double stirling(uint8_t n) /////////////////////////////////////////////////////////////////////////// // -// SEMIFACTORIAL +// SEMI_FACTORIAL // // exact ==> 20!! @@ -239,6 +239,53 @@ double dSemiFactorial(uint16_t n) } + +/////////////////////////////////////////////////////////////////////////// +// +// SKIP_FACTORIAL +// + +uint32_t skipFactorial(uint32_t n, uint32_t skip) +{ + if (skip == 0) return 0; + uint32_t f = 1; + while(n > skip) + { + f *= n; + n -= skip; + } + return f; +} + + +uint64_t skipFactorial64(uint32_t n, uint32_t skip) +{ + if (skip == 0) return 0; + uint64_t f = 1; + while(n > skip) + { + f *= n; + n -= skip; + } + return f; +} + + +// float (4 byte) +// double (8 byte) +double dSkipFactorial(uint32_t n, uint32_t skip) +{ + if (skip == 0) return 0; + double f = 1; + while(n > skip) // optimize like sSemiFactorial? + { + f *= n; + n -= skip; + } + return f; +} + + /////////////////////////////////////////////////////////////////////////// // // COMBINATIONS diff --git a/libraries/statHelpers/statHelpers.h b/libraries/statHelpers/statHelpers.h index 4b703878..9c8f5e27 100644 --- a/libraries/statHelpers/statHelpers.h +++ b/libraries/statHelpers/statHelpers.h @@ -2,7 +2,7 @@ // // FILE: statHelpers.h // AUTHOR: Rob Tillaart -// VERSION: 0.1.8 +// VERSION: 0.2.0 // PURPOSE: Arduino library with a number of statistic helper functions. // DATE: 2020-07-01 // URL: https://github.com/RobTillaart/statHelpers @@ -11,7 +11,7 @@ #include "Arduino.h" -#define STATHELPERS_LIB_VERSION (F("0.1.8")) +#define STATHELPERS_LIB_VERSION (F("0.2.0")) /////////////////////////////////////////////////////////////////////////// @@ -127,7 +127,7 @@ double dfactorial(uint8_t n); double stirling(uint8_t n); -// SEMIFACTORIAL +// SEMI_FACTORIAL // exact ==> 20!! uint32_t semiFactorial(uint8_t n); @@ -140,6 +140,15 @@ uint64_t semiFactorial64(uint8_t n); double dSemiFactorial(uint16_t n); +// SKIP_FACTORIAL (experimental) + +// note step must be larger than 0 +// note when step == 1 ==> factorial +// note when step == 2 ==> semiFactorial +uint32_t skipFactorial(uint32_t n, uint32_t skip); +uint64_t skipFactorial64(uint32_t n, uint32_t skip); +double dSkipFactorial(uint32_t n, uint32_t skip); + /////////////////////////////////////////////////////////////////////////// //