{"id":13807565,"url":"https://github.com/nin93/alea","last_synced_at":"2026-02-27T21:02:11.680Z","repository":{"id":55452361,"uuid":"257413015","full_name":"nin93/alea","owner":"nin93","description":"Repeatable pseudo-random sampling, CDF over most known probability distributions.","archived":false,"fork":false,"pushed_at":"2022-02-20T15:27:00.000Z","size":807,"stargazers_count":12,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-05-12T22:55:00.231Z","etag":null,"topics":["cdf","crystal","crystal-lang","cumulative-distribution-function","prng","random","random-draw","random-generation","random-number-generators"],"latest_commit_sha":null,"homepage":"https://nin93.github.io/alea/","language":"Crystal","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nin93.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-04-20T21:55:49.000Z","updated_at":"2024-01-03T14:16:58.000Z","dependencies_parsed_at":"2022-08-15T00:31:19.462Z","dependency_job_id":null,"html_url":"https://github.com/nin93/alea","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nin93%2Falea","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nin93%2Falea/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nin93%2Falea/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nin93%2Falea/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nin93","download_url":"https://codeload.github.com/nin93/alea/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253837400,"owners_count":21971982,"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":["cdf","crystal","crystal-lang","cumulative-distribution-function","prng","random","random-draw","random-generation","random-number-generators"],"created_at":"2024-08-04T01:01:26.943Z","updated_at":"2026-02-27T21:02:11.592Z","avatar_url":"https://github.com/nin93.png","language":"Crystal","funding_links":[],"categories":["Science and Data analysis"],"sub_categories":[],"readme":"# Alea\n\n[![Build Status](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Factions-badge.atrox.dev%2Fnin93%2Falea/badge%3Fref%3Dmaster\u0026label=Build%20Status\u0026style=flat-square)](https://actions-badge.atrox.dev/nin93/alea/goto?ref=master)\n[![Crystal](https://img.shields.io/badge/crystal-v0.36.0-24292e?style=flat-square\u0026logo=data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+PHN2ZyAgIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIgICB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIiAgIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyIgICB4bWxuczpzdmc9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiAgIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgICBoZWlnaHQ9IjY0LjAiICAgd2lkdGg9IjY0LjAiICAgeG1sOnNwYWNlPSJwcmVzZXJ2ZSIgICB2aWV3Qm94PSIwIDAgNjkuMDQxMTAxIDY4LjgwMDc4MyIgICB5PSIwcHgiICAgeD0iMHB4IiAgIGlkPSJMYXllcl8xIiAgIHZlcnNpb249IjEuMSI+PG1ldGFkYXRhICAgaWQ9Im1ldGFkYXRhMTUiPjxyZGY6UkRGPjxjYzpXb3JrICAgICAgIHJkZjphYm91dD0iIj48ZGM6Zm9ybWF0PmltYWdlL3N2Zyt4bWw8L2RjOmZvcm1hdD48ZGM6dHlwZSAgICAgICAgIHJkZjpyZXNvdXJjZT0iaHR0cDovL3B1cmwub3JnL2RjL2RjbWl0eXBlL1N0aWxsSW1hZ2UiIC8+PGRjOnRpdGxlPjwvZGM6dGl0bGU+PC9jYzpXb3JrPjwvcmRmOlJERj48L21ldGFkYXRhPjxkZWZzICAgaWQ9ImRlZnMxMyI+PC9kZWZzPjxzdHlsZSAgIGlkPSJzdHlsZTIiICAgdHlwZT0idGV4dC9jc3MiPi5zdDB7ZmlsbDpub25lO308L3N0eWxlPjxnICAgc3R5bGU9ImRpc3BsYXk6aW5saW5lIiAgIGlkPSJsYXllcjMiPjxwYXRoICAgICB0cmFuc2Zvcm09InJvdGF0ZSgtMC41MzY5MjE2LC0xMjYuNTM4MzQsMjExLjU1Njc0KSIgICAgIGQ9Ik0gMjkuODg4NjMsNTEuNjE5OTU0IDYuNjgxNzQ3MiwyNy44NTEyODUgMzguODY5NDYsMTkuNjM3ODcgWiIgICAgIGlkPSJwYXRoMTE0NyIgICAgIHN0eWxlPSJkaXNwbGF5OmlubGluZTtmaWxsOiNmZmZmZmY7ZmlsbC1vcGFjaXR5OjEiIC8+PC9nPjxyZWN0ICAgY2xhc3M9InN0MCIgICB3aWR0aD0iMzQwLjM5OTk5IiAgIGhlaWdodD0iMTM3LjciICAgaWQ9InJlY3Q2IiAgIHg9Ii0xMjIuMDEzODUiICAgeT0iLTMyLjQyMzkxMiIgICBzdHlsZT0iZmlsbDpub25lIiAvPjxnICAgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTEyMi4zMTQxNiwtMzIuMzYxNzE2KSIgICBzdHlsZT0iZGlzcGxheTppbmxpbmUiICAgaWQ9ImxheWVyMiI+PHBhdGggICAgIHN0eWxlPSJzdHJva2Utd2lkdGg6MC44NTk2NDU5NiIgICAgIGlkPSJwYXRoMTAxNiIgICAgIGQ9Im0gMTQ5LjE4OTkzLDM3LjEzNzMzMyBjIC0wLjA4NjUsMCAtMC4yNTgxNywwLjAwMTggLTAuMzQ0MTgsMC4wODczIGwgLTIxLjQ5MTA4LDIxLjQwMzg0OCBjIC0wLjA4NjUsMC4wODU5OSAtMC4wODYxLDAuMTcyMjY2IC0wLjA4NjEsMC4zNDQxOTIgbCA3LjgyMjQzLDI5LjIyNzk2IGMgMCwwLjA4NTk3IDAuMDg1MiwwLjE3MjYwNCAwLjI1NjksMC4yNTg1NzMgbCAyOS4zMTUyOCw3LjgyMjQ1IGMgMC4wODY0LDAgMC4yNTY1MywzLjY2ZS00IDAuMzQyNSwtMC4wODYxNCBsIDIxLjQ5MTI0LC0yMS40MDU0NiBjIDAuMDg2MiwtMC4xNzE5MzIgMC4xNzMxOCwtMC4yNTgyMjggMC4wODc3LC0wLjM0NDIwMSBsIC03LjgyNDIzLC0yOS4yMjc5MTMgYyAwLC0wLjA4NjAyIC0wLjA4NDcsLTAuMTcwOTIyIC0wLjI1Njg3LC0wLjI1Njg4OSB6IG0gOC41OTY0NywxNC4xODQxNTMgYyAwLDAuMDg1OTkgMC4wODU5LDAuMDg2OTQgMC4wODU5LDAuMTcyOTQgbCAtNy43MzY3OSwyOC43MTI1MDQgYyAwLDAuMDg2IC0wLjA4NzIsMC4wODYgLTAuMTcyOTUsMCBMIDEyOC45ODg0Myw1OS4yMzEyMzggYyAtMC4wODYxLC0wLjA4NjAxIDAsLTAuMDg2OTUgMCwtMC4xNzI5MzUgeiIgLz48L2c+PHJlY3QgICBzdHlsZT0iZmlsbDpub25lIiAgIHk9Ii0zMi40MjM5MTIiICAgeD0iLTEyMi4wMTM4NSIgICBpZD0icmVjdDEwMTAiICAgaGVpZ2h0PSIxMzcuNyIgICB3aWR0aD0iMzQwLjM5OTk5IiAgIGNsYXNzPSJzdDAiIC8+PC9zdmc+)](https://github.com/crystal-lang/crystal)\n[![Shard](https://img.shields.io/badge/shard-v0.3.0-orange?style=flat-square)](https://crystalshards.org/shards/github/nin93/alea)\n[![Docs](https://img.shields.io/badge/docs-GitHub_pages-blueviolet.svg?style=flat-square)](https://nin93.github.io/alea/)\n[![License](https://img.shields.io/badge/license-MIT-informational.svg?style=flat-square)](https://github.com/nin93/alea/blob/master/LICENSE.md)\n\nAlea is a collection of utilities to work with most known probability distributions,\nwritten in pure Crystal.\n\n\u003e **Note**: This project is in development state and many distributions are\n  still missing, as well as cumulative distribution functions, so keep in mind that\n  breaking changes may occur frequently.\n\n## Why Crystal?\n\nCrystal compiles to really fast native code without sacrificing any of the modern\nprogramming languages standards providing a nice and clean interface.\n\n## Index\n\n* [Features](#features)\n\t+ [Currently Available](#currently-available)\n\t+ [Supported Distributions](#supported-distributions)\n\t+ [Projects](#projects)\n* [Installation](#installation)\n* [Usage](#usage)\n\t+ [Sampling](#sampling)\n\t+ [Unsafe Methods](#unsafe-methods)\n\t+ [Pseudo Random Number Generators](#prngs)\n\t+ [Custom PRNG](#custom-prng)\n\t+ [Cumulative Distribution Functions](#cumulative-distribution-functions)\n\t+ [Documentation](#documentation)\n* [References](#references)\n* [Contributing](#contributing)\n* [Contributors](#contributors)\n\n## Features\n\n### Currently Available\n\n* PRNGs implementations\n* Random sampling (single/double precision)\n* Cumulative Distribution Functions (single/double precision)\n\n### Supported Distributions\n\n| Distribution  | Sampling (32 / 64)| CDF (32 / 64) |\n|:--------------|:-----------------:|:-------------:|\n| Beta          |        Y  Y       |      N  N     |\n| Chi-Square    |        Y  Y       |      Y  Y     |\n| Exponential   |        Y  Y       |      Y  Y     |\n| F-Snedecor    |        Y  Y       |      N  N     |\n| Gamma         |        Y  Y       |      Y  Y     |\n| Laplace       |        Y  Y       |      Y  Y     |\n| Log-Normal    |        Y  Y       |      Y  Y     |\n| Normal        |        Y  Y       |      Y  Y     |\n| Poisson       |        N  Y       |      N  Y     |\n| T-Student     |        Y  Y       |      N  N     |\n| Uniform       |        Y  Y       |      Y  Y     |\n\n### Projects\n\n* Distribution and empirical data statistical properties\n* Quantile Functions\n\n## Installation\n\n1. Add the dependency to your `shard.yml`:\n\n```yaml\ndependencies:\n  alea:\n    github: nin93/alea\n```\n\n2. Run `shards install`\n\n3. Import the library:\n\n```crystal\nrequire \"alea\"\n```\n\n## Usage\n\n### Sampling\n\n`Random` is the interface provided to perform sampling:\n```crystal\nrandom = Alea::Random(Alea::XSR128).new\nrandom.normal # =\u003e -0.36790519967553736 : Float64\n\n# Append '32' to call the single-precision version\nrandom.normal32 # =\u003e 0.19756398 : Float32\n```\n\nIt also accepts an initial seed to reproduce the same seemingly random events across runs:\n```crystal\nseed = 9377\nrandom = Alea::Random(Alea::XSR128).new(seed)\nrandom.exp # =\u003e 0.10203669577353723 : Float64\n```\n\n#### Unsafe Methods\n\nPlain sampling methods (such as `#normal`, `#gamma32`) performs checks \nover arguments passed to prevent bad data generation or inner exceptions.\nIn order to avoid checks (might be slow in a large data generation) you must use their\nunsafe version by prepending `next_` to them:\n```crystal\nrandom = Alea::Random(Alea::XSR128).new\nrandom.normal(loc: 0, sigma: 0)      # raises Alea::UndefinedError: sigma is 0 or negative.\nrandom.next_normal(loc: 0, sigma: 0) # these might raise internal exceptions.\n```\n\nTimings are definitely comparable, though: see the \n[benchmarks](https://github.com/nin93/alea/tree/master/benchmarks)\nfor direct comparisons between these methods.\n\n### PRNGs\n\n`Random` is actually a wrapper over a well defined pseudo-random number generator.\nThe basic generation of integers and floats comes from the underlying engine, more specifically\nfrom: `#next_u32`, returning a random `UInt32`, and `#next_u64`, returning a random `UInt64`.\nFloats are obtained by `ldexp` (load exponent) operations upon generated\nunsigned integers; signed integers are obtained by raw cast.\n\nCurrently implemented engines:\n+ `XSR128`  backed by *xoroshiro128++*   (32/64 bit)\n+ `XSR256`  backed by *xoshiro256++*     (32/64 bit)\n+ `MT19937` backed by *mersenne twister* (32/64 bit)\n\nThe digits in the class name stand for the overall period of the PRNG as a power of 2:\n`(2^N) - 1`, where `N` is the said number.\n\n`XSR256` and `XSR128` engines are from the [xoshiro](http://prng.di.unimi.it/) (XOR/shift/rotate)\ncollection, designed by Sebastiano Vigna and David Blackman: really fast generators promising\nexquisite statistical properties as well.\n\n`MT19937` engine is an implementation of the famous\n[Mersenne Twister](http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html), developed by Makoto\nMatsumoto and Takuji Nishimura: the most widely used PRNG passing most strict statistical tests.\n\n#### Custom PRNG\n\nAll PRNGs in this library inherit from a module: `PRNG`. You are allowed to build\nyour own custom PRNG by including the module and defining the methods needed by\n`Alea::Random` to ensure proper repeatability and sampling, as described in this \n[example](https://github.com/nin93/alea/blob/master/custom_prng.cr).\n\nIt is worth noting that in these implementations `#next_u32` and `#next_u64`\ndepend on different states and thus they are independent from each other,\nas well as `#next_f32` and `#next_f64` or `#next_i32` and `#next_i64`.\nIt is still fine, though, if both `#next_u32` and `#next_u64` rely on the same\nstate, if you want. I choose not to, as it makes state advancements unpredictable.\n\n### Cumulative Distribution Functions\n\n`CDF` is the interface used to calculate the Cumulative Distribution Functions.\nGiven *X* ~ *D* and a fixed quantile *x*, CDFs are defined as the functions that\nassociate *x* to the probability that the real-valued random *X* from the\ndistribution *D* will take a value less or equal to *x*.\n\nArguments passed to `CDF` methods to shape the distributions are analogous to\nthose used for sampling:\n```crystal\nAlea::CDF.normal(0.0)                       # =\u003e 0.5 : Float64\nAlea::CDF.normal(2.0, loc: 1.0, sigma: 0.5) # =\u003e 0.9772498680518208 : Float64\nAlea::CDF.chisq(5.279, df: 5.0)             # =\u003e 0.6172121213841358 : Float64\nAlea::CDF.chisq32(5.279, df: 5.0)           # =\u003e 0.61721206 : Float32\n```\n\n### Documentation\n\nDocumentation is hosted on [GitHub Pages](https://nin93.github.io/alea/).\n\n## Into The Wild\n\nHere is a list of the projects including alea:\n* [crystal-data/num.cr](https://github.com/crystal-data/num.cr)\n\n## Aknowledgments\n\nFully listed in [LICENSE.md](https://github.com/nin93/alea/tree/master/LICENSE.md):\n* [Crystal](https://github.com/crystal-lang/crystal) `Random` module for uniform sampling\n* [NumPy](https://github.com/numpy/numpy) `random` module for pseudo-random sampling methods\n* [NumPy](https://github.com/numpy/numpy) `mt19937` prng implementation\n* [JuliaLang](https://github.com/JuliaLang/julia) `random` module for ziggurat methods\n* [IncGammaBeta.jl](https://github.com/jkovacic/IncGammaBeta.jl) for incomplete gamma functions\n\n## Contributing\n\n1. Fork it (\u003chttps://github.com/nin93/alea/fork\u003e)\n2. Create your feature branch (`git checkout -b my-new-feature`)\n3. Commit your changes (`git commit -am 'Add some feature'`)\n4. Push to the branch (`git push origin my-new-feature`)\n5. Create a new Pull Request\n\n## Contributors\n\n- [Elia Franzella](https://github.com/nin93) - creator and maintainer\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnin93%2Falea","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnin93%2Falea","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnin93%2Falea/lists"}