{"id":20989861,"url":"https://github.com/robtillaart/stathelpers","last_synced_at":"2025-05-14T18:32:16.037Z","repository":{"id":42045668,"uuid":"276455504","full_name":"RobTillaart/statHelpers","owner":"RobTillaart","description":"Arduino library with a number of statistic helper functions.","archived":false,"fork":false,"pushed_at":"2024-04-13T09:17:39.000Z","size":37,"stargazers_count":5,"open_issues_count":0,"forks_count":1,"subscribers_count":3,"default_branch":"master","last_synced_at":"2024-08-07T18:27:06.997Z","etag":null,"topics":["arduino","combinations","factorial","permutations","statistics"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/RobTillaart.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null},"funding":{"github":"RobTillaart","custom":"https://www.paypal.me/robtillaart"}},"created_at":"2020-07-01T18:38:39.000Z","updated_at":"2023-10-13T20:23:35.000Z","dependencies_parsed_at":"2024-01-06T14:46:34.280Z","dependency_job_id":null,"html_url":"https://github.com/RobTillaart/statHelpers","commit_stats":null,"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RobTillaart%2FstatHelpers","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RobTillaart%2FstatHelpers/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RobTillaart%2FstatHelpers/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RobTillaart%2FstatHelpers/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/RobTillaart","download_url":"https://codeload.github.com/RobTillaart/statHelpers/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":225305753,"owners_count":17453441,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["arduino","combinations","factorial","permutations","statistics"],"created_at":"2024-11-19T06:26:29.193Z","updated_at":"2024-11-19T06:26:30.062Z","avatar_url":"https://github.com/RobTillaart.png","language":"C++","funding_links":["https://github.com/sponsors/RobTillaart","https://www.paypal.me/robtillaart"],"categories":[],"sub_categories":[],"readme":"\n[![Arduino CI](https://github.com/RobTillaart/statHelpers/workflows/Arduino%20CI/badge.svg)](https://github.com/marketplace/actions/arduino_ci)\n[![Arduino-lint](https://github.com/RobTillaart/statHelpers/actions/workflows/arduino-lint.yml/badge.svg)](https://github.com/RobTillaart/statHelpers/actions/workflows/arduino-lint.yml)\n[![JSON check](https://github.com/RobTillaart/statHelpers/actions/workflows/jsoncheck.yml/badge.svg)](https://github.com/RobTillaart/statHelpers/actions/workflows/jsoncheck.yml)\n[![GitHub issues](https://img.shields.io/github/issues/RobTillaart/statHelpers.svg)](https://github.com/RobTillaart/statHelpers/issues)\n\n[![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](https://github.com/RobTillaart/statHelpers/blob/master/LICENSE)\n[![GitHub release](https://img.shields.io/github/release/RobTillaart/statHelpers.svg?maxAge=3600)](https://github.com/RobTillaart/statHelpers/releases)\n[![PlatformIO Registry](https://badges.registry.platformio.org/packages/robtillaart/library/statHelpers.svg)](https://registry.platformio.org/libraries/robtillaart/statHelpers)\n\n\n# statHelpers\n\nArduino library with a number of statistic helper functions.\n\n\n## Description\n\nThis library contains functions that have the goal to help with \nbasic statistical calculations like permutations, combinations,\nand factorials.\n\nIt includes an experimental section for large numbers. \nNote that these are very computation (time) intensive so not suited for real time math :)\n\nTo print very large numbers - https://github.com/RobTillaart/PrintHelpers\n\n\n#### Related\n\n- https://github.com/RobTillaart/Correlation\n- https://github.com/RobTillaart/GST - Golden standard test metrics\n- https://github.com/RobTillaart/Histogram\n- https://github.com/RobTillaart/RunningAngle\n- https://github.com/RobTillaart/RunningAverage\n- https://github.com/RobTillaart/RunningMedian\n- https://github.com/RobTillaart/statHelpers - combinations \u0026 permutations\n- https://github.com/RobTillaart/Statistic\n\n\n## Interface\n\n```cpp\n#include \"statHelpers.h\"\n```\n\n### Permutation\n\nReturns how many different ways one can choose a set of k elements from a set of n. \nThe order does matter so (1, 2) is not equal to (2, 1). \nThe limits mentioned is the n for which all k still work.\n\n- **uint32_t permutations(n, k)** exact up to n = 12\n- **uint64_t permutations64(n, k)** exact up to n = 20\n- **double dpermutations(n, k)** not exact up to n = 34 (4 byte) or n = 170 (8 byte)\n\nIf you need a larger n but k is near 0 the functions will still work.\nTo which value of k the formulas work differs per value for n. \nNo formula found, and build in an overflow detection takes overhead, so that is not done.\n\n\n- **nextPermutation\u003cType\u003e(array, size)** given an array of type T it finds the next permutation\nof that array in a lexicographical way.  ABCD --\u003e ABDC. \nBased upon // http://www.nayuki.io/page/next-lexicographical-permutation-algorithm although \nother same code examples exist.\n\n\n### Factorial\n\n- **uint32_t factorial(n)** exact up to n = 12.\n- **uint64_t factorial64(n)** exact up to n = 20.  (Print 64 bit integers with my printHelpers)\n- **double dfactorial(n)** not exact up to n = 34 (4 byte) or n = 170 (8 byte).\n- **double stirling(n)** approximation function for factorial (right magnitude).\nConstant run-time.\n\n**dfactorial()** is quite accurate over the whole range.\n**stirling()** is up to 3x faster for large n (\u003e 100), \nbut accuracy is less than the **dfactorial()**, see example.\n\n\n### SemiFactorial\n\nSemiFactorials are like factorials but skipping every other.\nSemiFactorials are written as a number with two exclamation marks.\n \nSemiFactorial are defined for\n- **odd** values:  n!! == n x (n-2) x (n-4) ... x 1\n- **even** values: n!! == n x (n-2) x (n-4) ... x 2\n\nExample 12!! = 12 x 10 x 8 x 6 x 4 x 2 = 46080\n\n- **uint32_t semiFactorial(n)** exact up to 20!!\n- **uint64_t semiFactorial64(n)** exact up to 33!!  (Print 64 bit integers with printHelpers library)\n- **double dSemiFactorial(n)** not exact up to 56!! (4 byte) or 300!! (8 byte)\n\n\nNotes:  \n```\nn! = n!! x (n-1)!!\n``` \nThis formula allows to calculate the value of n! indirectly.\n\n\n### SkipFactorial (experimental)\n\n- **uint32_t skipFactorial(uint32_t n, uint32_t skip)** \n- **uint64_t skipFactorial64(uint32_t n, uint32_t skip)** \n- **double dSkipFactorial(uint32_t n, uint32_t skip)** \n\nSkipFactorials are like factorials and semiFactorials but they skip **skip** numbers.\n- **skipFactorial(12, 4)** = 12 x 8 x 4 = 384\n- **skipFactorial(17, 5)** = 17 x 12 x 7 x 2 = 2856\n- **skipFactorial(n, 1)** == **factorial(n)**\n- **skipFactorial(n, 2)** == **semiFactorial(n)**\n\nAs the maximum depends on both n and step sizze there is no single maximum for n.\nThis is similar to combinations and permutations.\n\nAn indicative table of maxima per function call, the larger the skip, the larger the maximum n.\nNote that for skip \u003c= 10 n still is an 8 bit number.\n\n|   function        |  n, 2   |  n, 3   |  n, 4   |  n, 5   |  n, 10  |  notes  |\n|:------------------|:-------:|:-------:|:-------:|:-------:|:-------:|:--------|\n|  skipFactorial    |   20    |   27    |   32    |    40   |    69   |  max expected smaller than 7 x skip when skip \u003e 10.\n|  skipFactorial64  |   33    |   45    |   55    |    66   |   115   |  max expected smaller than 12 x skip when skip \u003e 10.\n|  dSkipFactorial   |   56    |   77    |   95    |   115   |   200   |  float  (4 bytes)  max expected smaller than 20 x skip when skip \u003e 10.\n|  dSkipFactorial   |  300    |         |         |         |         |  double (8 bytes) \n\nNote that for the function the **max / skip** is decreasing when **skip grows**.\n\n\n### Combinations\n\nReturns how many different ways one can choose a set of k elements from a set of n. \nThe order does **not** matter so (1, 2) is equal to (2, 1). \nThe number of combinations grows fast so n is limited per function.\nThe limits mentioned is the n for which all k still work.\n\n- **uint32_t combinations(n, k)**     n = 0 .. 30 (iterative version)\n- **uint64_t combinations64(n, k)**   n = 0 .. 61 (iterative version)\n- **uint32_t rcombinations(n, k)**    n = 0 .. 30 (recursive version, slightly slower)\n- **uint64_t rcombinations64(n, k)**  n = 0 .. 61 (recursive version, slightly slower)\n- **double dcombinations(n, k)**      n = 0 .. 125 (4bit)  n = 0 .. 1020 (8 bit) \n\nIf you need a larger n but k is near 0 the functions will still work.\nTo which value of k the formulas work differs per value for n. \nNo formula found, and build in an overflow detection takes overhead, so that is not done.\n\n\n- **combPascal(n, k)** n = 0 .. 30 but due to double recursion per iteration it takes\ntime and a lot of it for larger values. Added for recreational purposes, limited tested.\nUses Pascal's triangle.\n\n\n## Notes\n\n- **perm1** is a sketch in the examples that shows a recursive permutation algorithm. \nIt generates all permutations of a given char string and allows you to process every instance.\nThis sketch is added to this library as it fits in the context.\n\n\n## Experimental \n\n#### 32 bit numbers\n\n- **void bigFactorial(uint32_t n, double \u0026mantissa, uint32_t \u0026exponent)** \nreturns a double mantissa between 0 and 10, and an integer exponent. \n- **void bigPermutation(uint32_t n, uint32_t k, double \u0026mantissa, uint32_t \u0026exponent)** \nreturns a double mantissa between 0 and 10, and an integer exponent. \n- **void bigCombination(uint32_t n, uint32_t k, double \u0026mantissa, uint32_t \u0026exponent)** \nreturns a double mantissa between 0 and 10, and an integer exponent. \n\nAn experimental **bigFactorial(n)** calculation to get an idea of the big numbers. \nit can calculate factorials up to an exponent of 4294967295 max.  100.000.000! can be \ndone in 38 minutes on an ESP32 at 240 MHz.  \nMaximum value for n is **518678059! ==  2.1718890e4294967292** a number that took ~10 hours to calculate. \n\nAn experimental **bigPermutation(n, k)** calculation, to handle big numbers too. \nMaximum value for n is **518678059** to have full range support. For small(er) \nvalues of k, n can even be much larger, but not larger than 4294967295 max.\n\nAn experimental **bigCombination(n, k)** calculation for big numbers. \nNot investigated what its maximum value is, but it should be higher than **518678059** as the number \nof combinations is always smaller than number of permutations.\n\n\n#### 64 bit numbers- not investigated\n\nTo have support for huge numbers one could upgrade the code to use uint64_t as parameter and \ninternally but calculating these values could take a lot of time, although **bigPermutations64(n, k)** \nand **bigCombinations64(n, k)** would work fast for small values of k. \n\n- **void bigFactorial64(uint64_t n, double \u0026mantissa, uint64_t \u0026exponent)** \nreturns a double mantissa between 0 and 10, and an integer exponent.\n- **void bigPermutation64(uint64_t n, uint64_t k, double \u0026mantissa, uint64_t \u0026exponent)** \nreturns a double mantissa between 0 and 10, and an integer exponent.\n- **void bigCombination64(uint64_t n, uint64_t k, double \u0026mantissa, uint64_t \u0026exponent)** \nreturns a double mantissa between 0 and 10, and an integer exponent.\n\nIf someone has found the limits of these 64 bit versions, please let me know.\n\n\n## Operation\n\nSee examples\n\n\n## Future\n\n#### Must\n\n#### Should\n\n- investigate valid range detection for a given (n, k) for combinations and permutations.\n- Look for optimizations\n\n#### Could\n\n- investigate a bigFloat class to do math for permutations and combinations to substantially larger values.\n- Look for ways to extend the scope\n- fill table for skipFactorial for **double**\n\n\n#### Wont\n\n\n## Support\n\nIf you appreciate my libraries, you can support the development and maintenance.\nImprove the quality of the libraries by providing issues and Pull Requests, or\ndonate through PayPal or GitHub sponsors.\n\nThank you,\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frobtillaart%2Fstathelpers","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frobtillaart%2Fstathelpers","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frobtillaart%2Fstathelpers/lists"}