{"id":15286686,"url":"https://github.com/jeffreysarnoff/fastrationals.jl","last_synced_at":"2025-09-02T17:18:54.453Z","repository":{"id":61797896,"uuid":"115686485","full_name":"JeffreySarnoff/FastRationals.jl","owner":"JeffreySarnoff","description":"Arithmetic with small and with very large rationals is made fast.","archived":false,"fork":false,"pushed_at":"2023-07-17T10:41:54.000Z","size":1062,"stargazers_count":22,"open_issues_count":1,"forks_count":5,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-08-17T18:33:06.148Z","etag":null,"topics":["high-performance","julia","rational-numbers"],"latest_commit_sha":null,"homepage":"","language":"Julia","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/JeffreySarnoff.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,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2017-12-29T04:29:02.000Z","updated_at":"2024-09-16T14:28:10.000Z","dependencies_parsed_at":"2025-04-13T03:42:41.960Z","dependency_job_id":"11815444-6272-433d-87d8-19852bbcb0d3","html_url":"https://github.com/JeffreySarnoff/FastRationals.jl","commit_stats":null,"previous_names":[],"tags_count":13,"template":false,"template_full_name":null,"purl":"pkg:github/JeffreySarnoff/FastRationals.jl","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JeffreySarnoff%2FFastRationals.jl","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JeffreySarnoff%2FFastRationals.jl/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JeffreySarnoff%2FFastRationals.jl/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JeffreySarnoff%2FFastRationals.jl/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/JeffreySarnoff","download_url":"https://codeload.github.com/JeffreySarnoff/FastRationals.jl/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JeffreySarnoff%2FFastRationals.jl/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":273318867,"owners_count":25084286,"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","status":"online","status_checked_at":"2025-09-02T02:00:09.530Z","response_time":77,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["high-performance","julia","rational-numbers"],"created_at":"2024-09-30T15:18:12.680Z","updated_at":"2025-09-02T17:18:54.389Z","avatar_url":"https://github.com/JeffreySarnoff.png","language":"Julia","funding_links":[],"categories":[],"sub_categories":[],"readme":"# FastRationals.jl\n\n### rationals with unreal performance \u003csup\u003e[𝓪](#source)\u003c/sup\u003e\n\n##### Copyright © 2017-2019 by Jeffrey Sarnoff. This work is released under The MIT License.\n----\n[![Build Status](https://travis-ci.org/JeffreySarnoff/FastRationals.jl.svg?branch=master)](https://travis-ci.org/JeffreySarnoff/FastRationals.jl)\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;[![codecov](https://codecov.io/gh/JeffreySarnoff/FastRationals.jl/branch/master/graph/badge.svg)](https://codecov.io/gh/JeffreySarnoff/FastRationals.jl)\n\n----\n## CAUTION: avoid FastRational{BigInt}s, FastQBig has slowed considerably\n----\n\n#### `FastRationals`\n\n- [`FastRational{Int64}`](https://github.com/JeffreySarnoff/FastRationals.jl#fastrationals-using-fast-integers)\n   - [performance relative to system rationals](https://github.com/JeffreySarnoff/FastRationals.jl/blob/master/README.md#performance-relative-to-system-rationals)\n\n- [`FastRational{BigInt}`](https://github.com/JeffreySarnoff/FastRationals.jl/blob/master/README.md#rationals-using-bigint)\n   - [what works well](https://github.com/JeffreySarnoff/FastRationals.jl#what-works-well)\n   - [what does not](https://github.com/JeffreySarnoff/FastRationals.jl#what-does-not-work-well)\n\n#### additional functionality\n- [rational compactification](https://github.com/JeffreySarnoff/FastRationals.jl#rational-compactification)\n- [enhanced rounding](https://github.com/JeffreySarnoff/FastRationals.jl#enhanced-rounding)\n\n----\n\n## FastRational types\n\nSystem rationals reduce the result of every rational input and each arithmetic operation to lowest terms.  FastRational types (`FastQ32`, `FastQ64`, `FastQBig`) reduce all rational inputs and reduce each rational value prior to presenting the value. Unlike system rationals, the result of a FastRational arithmetic operation is reduced only if overflow occur while it is being calculated.  With appropriately sized numerators and denominators, this takes less time. \n\n### FastRationals using fast integers\n\n- These types use fast integers : `FastRational{Int32} (FastQ32)` and `FastRational{Int64} (FastQ64)`.\n- Arithmetic is 12x..16x faster and matrix ops are 2x..6x faster when using appropriately ranged values.\n\n\nThese `FastRational` types are intended for use with _smaller_ rational values.  To compare two rationals or to calculate the sum, difference, product, or ratio of two rationals requires pairwise multiplication of the constituents of one by the constituents of the other.  Whether or not it overflow depends on the number of leading zeros (`leading_zeros`) in the binary representation of the absolute value of the numerator and the denominator given with each rational.  \n\nOf the numerator and denominator, we really want whichever is the larger in magnitude from each value used in an arithmetic op. These values determine whether or not their product may be formed without overflow. That is important to know. It is alright to work as though there is a possiblity of overflow where in fact no overflow will occur.  It is not alright to work as though there is no possiblity of overflow where in fact overflow will occur.  In the first instance, some unnecessary yet unharmful effort is extended.  In the second instance, an overflow error stops the computation.\n\n### FastRationals using large integers\n\n- __FastRationals__ exports types `FastRational{Int128} (FastQ128)` and `FastRational{BigInt} (FastQBig)`.\n\n    - `FastQ128` is 1.25x..2x faster than `Rational{Int128}` when using appropriately ranged values.\n\n    - `FastQBig` with large rationals speeds arithmetic by 25x..250x, and excels at `sum` and `prod`.\n    - `FastQBig` is best with numerators and denominators that have no more than 25_000 decimal digits.\n\n\n## performance relative to system rationals\n\n\n|    computation          | avg rel speedup |\n|:------------------------|:-----------------:|\n|      mul/div            |       20          |\n|      polyval            |       18          |\n|      add/sub            |       15          |\n|                         |                   |\n|      mat mul            |       10          |\n|      mat lu             |        5          |\n|      mat inv            |        3          |\n\n- avg is of FastQ32 and FastQ64\n- polynomial degree is 4, matrix size is 4x4\n\n- This script provided the [relative speedups](https://github.com/JeffreySarnoff/FastRationals.jl/blob/master/benchmarks/relspeed_Q32_Q64.jl).\n\n----\n## Rationals using BigInt\n\n#### harmonic numbers\n\n```\nusing FastRationals\n\nn = 10_000\nqs = [Rational{BigInt}(1,i) for i=1:n];\nfastqs = [FastQBig(1,i) for i=1:n];\nqs_time = @belapsed sum($qs);\nfastqs_time = @belapsed sum($fastqs);\nround(qs_time / fastqs_time, digits=2)\n```\n(I get 17x)\n\n#### 25_000 decimal digits\n\nUp to 25_000 digits, FastRational{BigInt}s `FastQBigInt` handily outperform `Rational{BigInt}`s in arithmetic calculation.\nWhen applied to appropriate computations, `FastQBigInt`s often run 2x-5x faster. These speedups were obtained evaluating\n[The Bailey–Borwein–Plouffe formula for π](https://github.com/JeffreySarnoff/FastRationals.jl/blob/master/benchmarks/BBP_for_pi.jl)\nat various depths (number of iterations) using `Rational{BigInt}` and `FastRational{BigInt}`. \n\n----\n\n#### what works well\n\nThe first column holds the number of random Rational{Int128}s used    \nto generate the random `Rational{BigInt}` values that were processed.\n\nThese relative performance numbers are throughput multipliers.    \nIn the time it takes to square an 8x8 Rational{BigInt} matrix,    \n__thirty__ 8x8 FastRational{BigInt} matrices may be squared.    \n\n- `sum` and `prod` \n\n|  n rationals       | `sum` relspeed | `prod` relspeed |\n|:------------------:|:--------------:|:---------------:| \n|  200               |    100         | 200             |\n|  500               |    200         | 350             |\n\n\n- matrix multiply and trace\n\n| n rationals        | `mul` relspeed  | `tr` relspeed |\n|:------------------:|:---------------:|:-------------:| \n| 64 (8x8)           |  15             |      10       |\n| 225 (15x15)        |  20             |      15       |\n\nThis script provided the [relative speedups](https://github.com/JeffreySarnoff/FastRationals.jl/blob/master/benchmarks/relspeed_QBigInt.jl).\n\n----\n\n#### what does not work well\n\nOther matrix functions (`det`, `lu`, `inv`) take much, much longer.  \u003e\u003e Fixes welcome \u003c\u003c.\n\nMeanwhile, some matrix functions convert first convert FastRationals to system rationals,    \ncompute the result, and reconvert to FastRationals.\n\n----\n\n### Most performant ranges using fast integers\n\n__FastRationals__ are at their most performant where overflow is absent or uncommon.  And vice versa: where overflow happens frequently, FastRationals have no intrinsic advantage.  How do we know what range of rational values are desireable?  We want to work with rational values that, for the most part, do not overflow when added, subtracted, multiplied or divided.  As rational calculation tends to grow numerator aor denominator magnitudes, it makes sense to further constrain the working range.  These tables are of some guidance. \n\n----\n\n  ###     ________  FastQ32  ______________________________  FastQ64  __________\n  |  range      | refinement  |                | range           | refinement     |\n  |:-----------:|:-----------:|:--------------:|:---------------:|:--------------:|\n  |             |             |                |                 |                |\n  |    ±215//1  |  ±1//215    |    sweet spot  |     ±55_108//1  |  ±1//55_108    |\n  |             |             |                |                 |                |\n  |    ±255//1  |  ±1//255    |    preferable  |     ±65_535//1  |  ±1//65_535    |\n  |             |             |                |                 |                |\n  |  ±1_023//1  |  ±1//1_023  |    workable    |   ±262_143//1   |  ±1//262_143   |\n  |             |             |                |                 |                |\n  | ±4_095//1   |  ±1//4_095  |    admissible  |  ±1_048_575//1  | ±1//1_048_575  |\n  |             |             |                |                 |                |\n\n\n\u003e The calculation of these magnitudes appears [here]( https://github.com/JeffreySarnoff/FastRationals.jl/blob/master/docs/src/thestatelessway.md#quantifying-the-desireable).\n\n----\n\n## additional functionality\n\n\n### rational compactification\n\n- `compactify`(rational_to_compactify, rational_radius_of_indifference)\n\nFrom all rationals that exist in the immediate neighborhood\u003csup\u003e[𝒃](#def)\u003c/sup\u003e\nof the rational_to_compactify, obtains the unique rational with the smallest denominator.\nAnd, if there be more than one, obtains that rational having the smallest numerator.\n\n\n```\nusing FastRationals\n\nmidpoint = 76_963 // 100_003\n\ncoarse_radius  = 1//64\nfine_radius    = 1//32_768\ntiny_radius    = 1//7_896_121_034\n\ncoarse_compact = compactify(midpoint, coarse_radius)      #         7//9\nfine_compact   = compactify(midpoint, fine_radius)        #       147//191\ntiny_compact   = compactify(midpoint, tiny_radius)        #    76_963//100_003\n\nabs(midpoint - tiny_compact)   \u003c tiny_radius    \u0026\u0026\nabs(midpoint - fine_compact)   \u003c fine_radius    \u0026\u0026\nabs(midpoint - coarse_compact) \u003c coarse_radius            #  true\n```\n\n\u003csup\u003e\u003ca name=\"neighborhood\"\u003e[𝒃](#def)\u003c/a\u003e\u003c/sup\u003e This `neighborhood` is given by \n ±_the radius of indifference_, centered at the rational to compactify. \n\n\n### enhanced rounding\n\n`FastRationals` support two kinds of directed rounding, one maintains type, the other yields an integer.\n- all rounding modes are available\n    - `RoundNearest`, `RoundUp`, `RoundDown`, `RoundToZero`, `RoundFromZero`\n```\n\u003e q = FastQ32(22, 7)\n(3//1, 3//1)\n\n\u003e round(q), round(q, RoundNearest), round(-q), round(-q, RoundNearest)\n(3//1, 3//1, -3//1, -3//1)\n\n\u003e round(q, RoundToZero), round(q, RoundFromZero), round(-q, RoundToZero), round(-q, RoundFromZero)\n(3//1, 4//1, -3//1, -4//1)\n\n\u003e round(q, RoundDown), round(q, RoundUp), round(-q, RoundDown), round(-q, RoundUp)\n(3//1, 4//1, -4//1, -3//1)\n\n\n\u003e round(Integer, q, RoundUp), typeof(round(Integer, q, RoundUp))\n4, Int32\n\n\u003e round(Int16, -q, RoundUp), typeof(round(Int16, -q, RoundUp))\n-3, Int16\n```\n\n----\n\n### what is not carried over from system rationals \n\n- There is no `FastRational` representation for Infinity\n- There is no support for comparing a `FastRational` with NaN\n\n----\n\n## more about it\n\n\u003e [Context Rather Than State](https://github.com/JeffreySarnoff/FastRationals.jl/blob/master/docs/src/thestatelessway.md)\n\n\u003e [what slows FastRationals](https://github.com/JeffreySarnoff/FastRationals.jl/blob/master/docs/src/metaphoricalflashlight.md)\n\n\u003e [the `mayoverflow` predicate](https://github.com/JeffreySarnoff/FastRationals.jl/blob/master/docs/src/mayoverflow.md)\n\n----\n\n## acknowledgements\n\nKlaus Crusius has contributed to this effort.\n\n## references\n\nThis work stems from a [discussion](https://github.com/JuliaLang/julia/issues/11522) that began in 2015.\n\nThe [rational compactifying algorithm](https://dl.acm.org/citation.cfm?id=2733711\u0026dl=ACM\u0026coll=DL) paper is in the ACM digital library. \n\n----\n\n\u003csup\u003e\u003ca name=\"source\"\u003e[𝓪](#attribution)\u003c/a\u003e\u003c/sup\u003e Harmen Stoppels on 2019-06-14\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjeffreysarnoff%2Ffastrationals.jl","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjeffreysarnoff%2Ffastrationals.jl","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjeffreysarnoff%2Ffastrationals.jl/lists"}