0.2.0 statHelpers

This commit is contained in:
Rob Tillaart 2024-01-06 15:16:37 +01:00
parent 61683ef3e6
commit 047d262340
18 changed files with 272 additions and 52 deletions

View File

@ -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/). 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 ## [0.1.8] - 2023-11-22
- update readme.md - update readme.md
## [0.1.7] - 2023-03-15 ## [0.1.7] - 2023-03-15
- update readme.md - update readme.md
- update GitHub actions - update GitHub actions

View File

@ -1,6 +1,6 @@
MIT License 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 Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View File

@ -81,18 +81,52 @@ but accuracy is less than the **dfactorial()**, see example.
### SemiFactorial ### SemiFactorial
SemiFactorials are like factorials but skipping every other. 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!! - **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) - **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: 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 ### Combinations
@ -184,9 +218,8 @@ See examples
- investigate a bigFloat class to do math for permutations and combinations to substantially larger values. - investigate a bigFloat class to do math for permutations and combinations to substantially larger values.
- Look for ways to extend the scope - 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) - fill table for skipFactorial for **double**
- e.g. skipFactorial(12, 4) = 12 x 8 x 4.
- skipFactorial(n, 2) == semiFactorial(n);
#### Wont #### Wont

View File

@ -18,6 +18,9 @@ void setup()
{ {
Serial.begin(115200); Serial.begin(115200);
Serial.println(__FILE__); Serial.println(__FILE__);
Serial.print("STATHELPERS_LIB_VERSION: ");
Serial.println(STATHELPERS_LIB_VERSION);
Serial.println();
Serial.println("dcombinations(n, k); "); Serial.println("dcombinations(n, k); ");
delay(10); delay(10);
@ -63,7 +66,7 @@ void setup()
Serial.print(expo); Serial.print(expo);
Serial.println(); Serial.println();
} }
//Serial.println(); // Serial.println();
} }
duration1 = micros() - start; duration1 = micros() - start;
Serial.println(duration1); Serial.println(duration1);
@ -78,5 +81,5 @@ void loop()
} }
// -- END OF FILE -- // -- END OF FILE --

View File

@ -7,7 +7,7 @@
#include "statHelpers.h" #include "statHelpers.h"
#include "printHelpers.h" // to print large numbers.... #include "printHelpers.h" // to print large numbers ...
uint32_t start, duration1, duration2, duration3; uint32_t start, duration1, duration2, duration3;
@ -17,6 +17,9 @@ void setup()
{ {
Serial.begin(115200); Serial.begin(115200);
Serial.println(__FILE__); Serial.println(__FILE__);
Serial.print("STATHELPERS_LIB_VERSION: ");
Serial.println(STATHELPERS_LIB_VERSION);
Serial.println();
uint32_t m = 10000001; uint32_t m = 10000001;
double mant = 0; double mant = 0;
@ -77,5 +80,5 @@ void loop()
} }
// -- END OF FILE -- // -- END OF FILE --

View File

@ -18,6 +18,10 @@ void setup()
{ {
Serial.begin(115200); Serial.begin(115200);
Serial.println(__FILE__); Serial.println(__FILE__);
Serial.print("STATHELPERS_LIB_VERSION: ");
Serial.println(STATHELPERS_LIB_VERSION);
Serial.println();
/////////////////////////////////////////// ///////////////////////////////////////////
@ -123,7 +127,8 @@ void setup()
Serial.println(); Serial.println();
*/ */
// pick 1000 persons from 4294967295 (maxLong)
// pick 1000 persons from 4294967295 (maxLong)
double mant = 0; double mant = 0;
uint32_t expo = 0; uint32_t expo = 0;
bigPermutations(4294967295, 1000, mant, expo); bigPermutations(4294967295, 1000, mant, expo);
@ -141,5 +146,5 @@ void loop()
} }
// -- END OF FILE -- // -- END OF FILE --

View File

@ -18,6 +18,10 @@ void setup()
{ {
Serial.begin(115200); Serial.begin(115200);
Serial.println(__FILE__); Serial.println(__FILE__);
Serial.print("STATHELPERS_LIB_VERSION: ");
Serial.println(STATHELPERS_LIB_VERSION);
Serial.println();
Serial.println("combinations(n, k)"); Serial.println("combinations(n, k)");
delay(10); delay(10);
@ -35,7 +39,7 @@ void setup()
// Serial.print(combinations(n, k)); // Serial.print(combinations(n, k));
// Serial.println(); // Serial.println();
} }
//Serial.println(); // Serial.println();
} }
duration1 = micros() - start; duration1 = micros() - start;
Serial.println(duration1); Serial.println(duration1);
@ -57,7 +61,7 @@ void setup()
// Serial.print(combinations(n, k)); // Serial.print(combinations(n, k));
// Serial.println(); // Serial.println();
} }
//Serial.println(); // Serial.println();
} }
duration1 = micros() - start; duration1 = micros() - start;
Serial.println(duration1); Serial.println(duration1);
@ -80,7 +84,7 @@ void setup()
// Serial.print(print64(combinations64(n, k))); // Serial.print(print64(combinations64(n, k)));
// Serial.println(); // Serial.println();
} }
//Serial.println(); // Serial.println();
} }
duration1 = micros() - start; duration1 = micros() - start;
Serial.println(duration1); Serial.println(duration1);
@ -101,7 +105,7 @@ void setup()
// Serial.print(print64(combinations64(n, k))); // Serial.print(print64(combinations64(n, k)));
// Serial.println(); // Serial.println();
} }
//Serial.println(); // Serial.println();
} }
duration1 = micros() - start; duration1 = micros() - start;
Serial.println(duration1); Serial.println(duration1);
@ -126,7 +130,7 @@ void setup()
// Serial.print(comb(n, k)); // Serial.print(comb(n, k));
// Serial.println(); // Serial.println();
} }
//Serial.println(); // Serial.println();
} }
duration1 = micros() - start; duration1 = micros() - start;
Serial.println(duration1); Serial.println(duration1);
@ -141,5 +145,5 @@ void loop()
} }
// -- END OF FILE -- // -- END OF FILE --

View File

@ -7,7 +7,7 @@
#include "statHelpers.h" #include "statHelpers.h"
#include "printHelpers.h" // to print large numbers.... #include "printHelpers.h" // to print large numbers....
uint32_t start, duration1, duration2; uint32_t start, duration1, duration2;
@ -17,6 +17,10 @@ void setup()
{ {
Serial.begin(115200); Serial.begin(115200);
Serial.println(__FILE__); Serial.println(__FILE__);
Serial.print("STATHELPERS_LIB_VERSION: ");
Serial.println(STATHELPERS_LIB_VERSION);
Serial.println();
int m = 35; int m = 35;
if (sizeof(double) == 8) m = 175; if (sizeof(double) == 8) m = 175;
@ -94,5 +98,5 @@ void loop()
} }
// -- END OF FILE -- // -- END OF FILE --

View File

@ -7,7 +7,7 @@
#include "statHelpers.h" #include "statHelpers.h"
#include "printHelpers.h" // to print large numbers.... #include "printHelpers.h" // to print large numbers....
uint32_t start, duration1, duration2, duration3; uint32_t start, duration1, duration2, duration3;
@ -17,6 +17,10 @@ void setup()
{ {
Serial.begin(115200); Serial.begin(115200);
Serial.println(__FILE__); Serial.println(__FILE__);
Serial.print("STATHELPERS_LIB_VERSION: ");
Serial.println(STATHELPERS_LIB_VERSION);
Serial.println();
int m = 35; int m = 35;
int decimals = 7; int decimals = 7;
@ -67,5 +71,5 @@ void loop()
} }
// -- END OF FILE -- // -- END OF FILE --

View File

@ -21,7 +21,9 @@ void setup()
{ {
Serial.begin(115200); Serial.begin(115200);
Serial.println(__FILE__); Serial.println(__FILE__);
Serial.print("STATHELPERS_LIB_VERSION: ");
Serial.println(STATHELPERS_LIB_VERSION);
Serial.println();
Serial.println("120 permutations + print"); Serial.println("120 permutations + print");
do do
@ -32,6 +34,7 @@ void setup()
} }
while (nextPermutation<char>(hello, 5)); while (nextPermutation<char>(hello, 5));
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
Serial.println("timing 720 permutations + print"); Serial.println("timing 720 permutations + print");
@ -52,6 +55,7 @@ void setup()
Serial.println(duration1); Serial.println(duration1);
delay(10); delay(10);
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
start = micros(); start = micros();
@ -70,5 +74,5 @@ void loop()
} }
// -- END OF FILE -- // -- END OF FILE --

View File

@ -2,26 +2,29 @@
// FILE: perm1.ino // FILE: perm1.ino
// AUTHOR: Rob Tillaart // AUTHOR: Rob Tillaart
// DATE: 2010-11-23 // DATE: 2010-11-23
// PUPROSE: demo permutations // PURPOSE: demo permutations
// URL: https://github.com/RobTillaart/statHelpers
// //
// //
// WARNING TAKES LONG // WARNING TAKES LONG
// ======================================================================== // ========================================================================
// ESP32 @ 240 MHz string length 8 ==> ~8100 milliseconds => printing!! // ESP32 @ 240 MHz string length 8 ==> ~8100 milliseconds => printing!!
// UNO no printing string length 8 ==> ~431 milliseconds // UNO no printing string length 8 ==> ~431 milliseconds
// UNO no printing string length 10 ==> ~38763 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; uint32_t start, stop;
void permutate(char * array, uint8_t n) 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; return;
} }
@ -46,7 +49,12 @@ void permutate(char * array, uint8_t n)
void setup() void setup()
{ {
Serial.begin(500000); 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.println("Will take some time..");
Serial.print("perm1 strlen: "); Serial.print("perm1 strlen: ");
Serial.println(strlen(permstring)); Serial.println(strlen(permstring));
@ -65,5 +73,4 @@ void loop()
} }
// -- END OF FILE -- // -- END OF FILE --

View File

@ -18,6 +18,10 @@ void setup()
{ {
Serial.begin(115200); Serial.begin(115200);
Serial.println(__FILE__); Serial.println(__FILE__);
Serial.print("STATHELPERS_LIB_VERSION: ");
Serial.println(STATHELPERS_LIB_VERSION);
Serial.println();
Serial.println("permutations(n, k)"); Serial.println("permutations(n, k)");
delay(10); delay(10);
@ -40,6 +44,7 @@ void setup()
Serial.println(duration1); Serial.println(duration1);
Serial.println(); Serial.println();
/////////////////////////////////////////// ///////////////////////////////////////////
Serial.println("permutations64(n, k)"); Serial.println("permutations64(n, k)");
@ -62,6 +67,7 @@ void setup()
Serial.println(duration1); Serial.println(duration1);
Serial.println(); Serial.println();
/////////////////////////////////////////// ///////////////////////////////////////////
Serial.println("dpermutations(n, k) - double can be 4 or 8 bit."); Serial.println("dpermutations(n, k) - double can be 4 or 8 bit.");
@ -95,5 +101,5 @@ void loop()
} }
// -- END OF FILE -- // -- END OF FILE --

View File

@ -7,7 +7,7 @@
#include "statHelpers.h" #include "statHelpers.h"
#include "printHelpers.h" // to print large numbers.... #include "printHelpers.h" // to print large numbers....
uint32_t start, duration1, duration2, duration3; uint32_t start, duration1, duration2, duration3;
@ -17,6 +17,9 @@ void setup()
{ {
Serial.begin(115200); Serial.begin(115200);
Serial.println(__FILE__); Serial.println(__FILE__);
Serial.print("STATHELPERS_LIB_VERSION: ");
Serial.println(STATHELPERS_LIB_VERSION);
Serial.println();
int m = 60; int m = 60;
if (sizeof(double) == 8) m = 301; if (sizeof(double) == 8) m = 301;
@ -39,7 +42,7 @@ void setup()
delay(100); delay(100);
uint8_t n = 25; uint8_t n = 25;
start = micros(); start = micros();
double d1 = semiFactorial(n); // will fail but indicative double d1 = semiFactorial(n); // will fail but indicative
duration1 = micros() - start; duration1 = micros() - start;
start = micros(); start = micros();
double d2 = semiFactorial64(n); double d2 = semiFactorial64(n);
@ -74,5 +77,5 @@ void loop()
} }
// -- END OF FILE -- // -- END OF FILE --

View File

@ -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 --

View File

@ -15,7 +15,7 @@
"type": "git", "type": "git",
"url": "https://github.com/RobTillaart/statHelpers.git" "url": "https://github.com/RobTillaart/statHelpers.git"
}, },
"version": "0.1.8", "version": "0.2.0",
"license": "MIT", "license": "MIT",
"frameworks": "*", "frameworks": "*",
"platforms": "*", "platforms": "*",

View File

@ -1,5 +1,5 @@
name=statHelpers name=statHelpers
version=0.1.8 version=0.2.0
author=Rob Tillaart <rob.tillaart@gmail.com> author=Rob Tillaart <rob.tillaart@gmail.com>
maintainer=Rob Tillaart <rob.tillaart@gmail.com> maintainer=Rob Tillaart <rob.tillaart@gmail.com>
sentence=Arduino library with a number of statistic helper functions. sentence=Arduino library with a number of statistic helper functions.

View File

@ -1,7 +1,7 @@
// //
// FILE: statHelpers.cpp // FILE: statHelpers.cpp
// AUTHOR: Rob Tillaart // AUTHOR: Rob Tillaart
// VERSION: 0.1.8 // VERSION: 0.2.0
// PURPOSE: Arduino library with a number of statistic helper functions. // PURPOSE: Arduino library with a number of statistic helper functions.
// DATE: 2020-07-01 // DATE: 2020-07-01
// URL: https://github.com/RobTillaart/statHelpers // URL: https://github.com/RobTillaart/statHelpers
@ -190,7 +190,7 @@ double stirling(uint8_t n)
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// //
// SEMIFACTORIAL // SEMI_FACTORIAL
// //
// exact ==> 20!! // 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 // COMBINATIONS

View File

@ -2,7 +2,7 @@
// //
// FILE: statHelpers.h // FILE: statHelpers.h
// AUTHOR: Rob Tillaart // AUTHOR: Rob Tillaart
// VERSION: 0.1.8 // VERSION: 0.2.0
// PURPOSE: Arduino library with a number of statistic helper functions. // PURPOSE: Arduino library with a number of statistic helper functions.
// DATE: 2020-07-01 // DATE: 2020-07-01
// URL: https://github.com/RobTillaart/statHelpers // URL: https://github.com/RobTillaart/statHelpers
@ -11,7 +11,7 @@
#include "Arduino.h" #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); double stirling(uint8_t n);
// SEMIFACTORIAL // SEMI_FACTORIAL
// exact ==> 20!! // exact ==> 20!!
uint32_t semiFactorial(uint8_t n); uint32_t semiFactorial(uint8_t n);
@ -140,6 +140,15 @@ uint64_t semiFactorial64(uint8_t n);
double dSemiFactorial(uint16_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);
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// //