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/).
## [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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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",
"url": "https://github.com/RobTillaart/statHelpers.git"
},
"version": "0.1.8",
"version": "0.2.0",
"license": "MIT",
"frameworks": "*",
"platforms": "*",

View File

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

View File

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

View File

@ -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);
///////////////////////////////////////////////////////////////////////////
//