{"id":25067353,"url":"https://github.com/digitalheir/semiring-js","last_synced_at":"2025-04-14T20:12:05.298Z","repository":{"id":14527275,"uuid":"76684845","full_name":"digitalheir/semiring-js","owner":"digitalheir","description":"💫 A library for working with ring-like algebraic structures that implements some common semirings","archived":false,"fork":false,"pushed_at":"2023-03-14T21:49:45.000Z","size":2480,"stargazers_count":8,"open_issues_count":1,"forks_count":1,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-04-14T20:11:59.107Z","etag":null,"topics":["abstract-algebra","algebra","algebraic-structures","algebras","javascript","log-semiring","mathematics","probability-semiring","rig","semiring","string-semiring","tropical","underflow"],"latest_commit_sha":null,"homepage":"https://digitalheir.github.io/semiring-js/","language":"TypeScript","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/digitalheir.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-12-16T20:51:16.000Z","updated_at":"2022-11-14T04:46:38.000Z","dependencies_parsed_at":"2023-01-11T18:50:15.578Z","dependency_job_id":null,"html_url":"https://github.com/digitalheir/semiring-js","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/digitalheir%2Fsemiring-js","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/digitalheir%2Fsemiring-js/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/digitalheir%2Fsemiring-js/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/digitalheir%2Fsemiring-js/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/digitalheir","download_url":"https://codeload.github.com/digitalheir/semiring-js/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248952350,"owners_count":21188426,"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":["abstract-algebra","algebra","algebraic-structures","algebras","javascript","log-semiring","mathematics","probability-semiring","rig","semiring","string-semiring","tropical","underflow"],"created_at":"2025-02-06T20:55:34.350Z","updated_at":"2025-04-14T20:12:05.280Z","avatar_url":"https://github.com/digitalheir.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"![Build Status](https://travis-ci.org/digitalheir/semiring-js.svg?branch=master)\n[![npm version](https://badge.fury.io/js/semiring.svg)](https://www.npmjs.com/package/semiring)\n![License](https://img.shields.io/npm/l/semiring.svg)\n[![Code Climate](https://codeclimate.com/github/digitalheir/semiring-js/badges/gpa.svg)](https://codeclimate.com/github/digitalheir/bibliography-js)\n\n# Semiring.js\nA simple library for working with [ring-like algebraic structures](https://en.wikipedia.org/wiki/Semiring) in Javascript that implements some common semirings. This library does not validate properties of the defined structures, so you could actually define any algebraic structure that has some notion of 'plus' and 'times'. It is a simple utility library I needed for my own purposes: I am not trying to implement all abstract algebra in here.\n\n[Live demo in browser](https://digitalheir.github.io/semiring-js)\n\nWritten in Typescript, published as a [commonjs modules on NPM](https://www.npmjs.com/package/semiring) and a [single-file minified UMD module on GitHub](https://github.com/digitalheir/semiring-js/releases) in vulgar ES5.\n\nNote that the set `S` on which the operators apply is defined through generics, eg. `Semiring\u003cnumber\u003e`. If you don't use Typescript, this behaviour should come from your own logic.\n\nThis library currently implements the following semirings:\n\n* [Probability semiring](#probability-semiring)\n* [Log semiring](#log-semiring)\n* [Tropical semiring](#tropical-semiring)\n* [Boolean Semiring](#boolean-semiring)\n* [String Semiring](#string-semiring)\n\n# Motivation\n\nI have two uses for this library:\n\n* I want to make a long probabilistic computation 0.1 * 0.1 * ... * 0.1, and at some point Javascript's floating point arithmetic will be unable to represent a number so small, leading to arithmetic underflow. To counter, we use the Log semiring which holds the `-log` value of the probability. So it maps the numbers between 0 and 1 to the numbers between infinity and zero, skewed towards lower probabilities:\n#### Graph plot of f(x) = -log(x)\n\n![Graph for f(x) = -log x](https://user-images.githubusercontent.com/178797/200821928-991c99b7-572e-4322-9d58-13e412041e2a.png)\n\n* I want to create an arithmetic expression of which values may change over time, i.e. pass around a value like `(x + 5) * 2`, and `x` is a pointer to a changing value. So I need an abstract expression tree, basically.\n\n# Usage\n````js\nimport {\n    LogSemiring,\n    makeDeferrable,\n    BooleanSemiring,\n    fromProbabilityToMinusLog as fromProbability,\n    toProbabilityFromMinusLog as toProbability,\n    AtomicValue,\n    Bool\n} from \"semiring\";\n\nlet minLogProb = fromProbability(1)\n\n/**\n * First use case: 1.0 * (0.1 * 0.1 ...a thousand times)\n */\nfor(let i=0;i\u003c1000;i++) {\n    minLogProb = LogSemiring.times(\n        minLogProb,\n        fromProbability(0.1)\n    );\n}\n\nconsole.log(minLogProb); // -log(1.0e-1000) = 2302.58, comfortable :)\nconsole.log(toProbability(minLogProb)); // 1.0e-1000, rounded to 0 :(\n\n/**\n * Second use case: create an expression tree with some two binary operators\n */\n\nconst deferrableBooleanSemiring = makeDeferrable(BooleanSemiring);\nconst AND = deferrableBooleanSemiring.times;\nconst OR = deferrableBooleanSemiring.plus;\n\nconst changeMyValue = new AtomicValue(false);\n \nconst TRUE = Bool.TRUE;\nconst FALSE = Bool.FALSE;\n\n/**\n *       OR\n *    /      \\\n * FALSE     AND\n *         /     \\\n *      {false}  TRUE\n */\nconst expressionTree = OR(FALSE, AND(changeMyValue, TRUE));\n\nconsole.log(expressionTree.resolve()); // \u003e false\nchangeMyValue.value = !changeMyValue.value; // Change expression tree\n/**\n *       OR\n *    /      \\\n * FALSE     AND\n *         /     \\\n *      {true}  TRUE\n */\nconsole.log(expressionTree.resolve()); // \u003e true\n\n````\n\n## Probability semiring\nThis semiring implements common notion of calculating probabilties.\n\n|Element set|⊕|⊗|0̅|1̅|\n|---|---|---|---|---|\n|Positive real numbers (**R**+)|+|*|0.0|1.0|\n\nFor example: `0.5 ⊗ 1.0 = 0.5`, `0.2 ⊕ 0.7 = 0.9`.\n\n````js\nimport {\n    ProbabilitySemiring\n} from \"semiring\";\n\nconsole.log(ProbabilitySemiring.times(0.5, 0.5)); // 0.25\n````\n\n## Log semiring\nA semiring usually used for multiplying numbers close to zero, to avoid arithmetic underflow.\n\n|Element set|⊕|⊗|0̅|1̅|\n|---|---|---|---|---|\n|Positive real numbers (**R**+) including ±∞|-log(e^{-x} + e^{-y})|+|+∞|0|\n\n\nFor example: \n`p = -log(0.1)`\n`q = -log(0.5)`\n\n`p ⊕ q = -log(e^-p + e^-q) = -log(0.6)`.\n\n`p ⊕ q = p + q = -log(0.05)`.\n\n````js\nimport {\n    LogSemiring\n} from \"semiring\";\n\n````\n\n## Boolean semiring\nA semiring that represents Boolean logic.\n\n|Element set|⊕|⊗|0̅|1̅|\n|---|---|---|---|---|\n|{True, False}|∨|∧|False|True|\n\n\nFor example: \n`True ⊕ False = True`.\n\n`True ⊗ False = False`.\n\n````js\nimport {\n    BooleanSemiring\n} from \"semiring\";\n\n````\n\n## Tropical semiring\nA semiring that describes [Tropical geometry](https://en.wikipedia.org/wiki/Tropical_geometry). An interesting application of this semiring was made by [Paul Klemperer for use in auctions during the financial crisis](https://www.theguardian.com/science/video/2013/jul/12/geometry-banking-crisis-video).\n\n|Element set|⊕|⊗|0̅|1̅|\n|---|---|---|---|---|\n|Real numbers **R** including ∞|min|+|∞|0|\n\nFor example: \n`4 ⊕ ∞ = 4`.\n\n`4 ⊗ 4 = 8`.\n\n````js\nimport {\n    TropicalSemiring\n} from \"semiring\";\n\n````\n\n## String semiring\nA semiring of formal languages. Used in automaton theory. ([An unweighted functional transducer can be seen as as a weighted automaton over the string semiring.](http://www.openfst.org/twiki/pub/FST/FstHltTutorial/tutorial_part1.pdf))\n\n|Element set|⊕|⊗|0̅|1̅|\n|---|---|---|---|---|\n|All languages over an alphabet Σ|∪|L1 ⊗ L2 = {w⋅v \\| w ∈ L1, v ∈ L2}|{}|{\"\"}|\n\nFor example: \n`{a, b, c} ⊕ {ab} = {a, b, c, ab}`.\n\n`{ab, ac} ⊗ {ab} = {abab, acab}`.\n\n````js\nimport {\n    StringSemiring\n} from \"semiring\";\n\n````\n\n## License\n[MIT](https://github.com/digitalheir/semiring-js/blob/master/LICENSE)\n\n## Contact\nMaarten Trompper \u003c\u003cmaartentrompper@freedom.nl\u003e\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdigitalheir%2Fsemiring-js","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdigitalheir%2Fsemiring-js","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdigitalheir%2Fsemiring-js/lists"}