{"id":16661431,"url":"https://github.com/bodigrim/poly","last_synced_at":"2025-09-11T14:08:14.254Z","repository":{"id":34681080,"uuid":"182565984","full_name":"Bodigrim/poly","owner":"Bodigrim","description":"Fast polynomial arithmetic in Haskell (dense and sparse, univariate and multivariate, usual and Laurent)","archived":false,"fork":false,"pushed_at":"2023-10-15T19:06:54.000Z","size":405,"stargazers_count":65,"open_issues_count":5,"forks_count":6,"subscribers_count":8,"default_branch":"master","last_synced_at":"2024-04-25T23:02:16.238Z","etag":null,"topics":["dense-univariate-polynomials","polynomial-arithmetic","polynomial-division","polynomial-multiplication","polynomials","sparse-multivariate-polynomials","sparse-univariate-polynomials"],"latest_commit_sha":null,"homepage":"http://hackage.haskell.org/package/poly","language":"Haskell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Bodigrim.png","metadata":{"files":{"readme":"README.md","changelog":"changelog.md","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}},"created_at":"2019-04-21T18:01:42.000Z","updated_at":"2024-01-22T16:38:50.000Z","dependencies_parsed_at":"2024-10-12T10:45:05.254Z","dependency_job_id":null,"html_url":"https://github.com/Bodigrim/poly","commit_stats":{"total_commits":188,"total_committers":4,"mean_commits":47.0,"dds":0.04255319148936165,"last_synced_commit":"cada8b449176e59ae744b15b19cb5ff31bb43f3f"},"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Bodigrim%2Fpoly","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Bodigrim%2Fpoly/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Bodigrim%2Fpoly/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Bodigrim%2Fpoly/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Bodigrim","download_url":"https://codeload.github.com/Bodigrim/poly/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243730867,"owners_count":20338729,"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":["dense-univariate-polynomials","polynomial-arithmetic","polynomial-division","polynomial-multiplication","polynomials","sparse-multivariate-polynomials","sparse-univariate-polynomials"],"created_at":"2024-10-12T10:35:01.299Z","updated_at":"2025-03-15T12:30:32.621Z","avatar_url":"https://github.com/Bodigrim.png","language":"Haskell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# poly [![Hackage](https://img.shields.io/hackage/v/poly.svg)](https://hackage.haskell.org/package/poly) [![Stackage LTS](https://www.stackage.org/package/poly/badge/lts)](https://www.stackage.org/lts/package/poly) [![Stackage Nightly](https://www.stackage.org/package/poly/badge/nightly)](https://www.stackage.org/nightly/package/poly) [![Coverage Status](https://coveralls.io/repos/github/Bodigrim/poly/badge.svg)](https://coveralls.io/github/Bodigrim/poly)\n\nHaskell library for univariate and multivariate polynomials, backed by `Vector`s.\n\n```haskell\n\u003e -- Univariate polynomials\n\u003e (X + 1) + (X - 1) :: VPoly Integer\n2 * X\n\u003e (X + 1) * (X - 1) :: UPoly Int\n1 * X^2 + (-1)\n\n\u003e -- Multivariate polynomials\n\u003e (X + Y) * (X - Y) :: VMultiPoly 2 Integer\n1 * X^2 + (-1) * Y^2\n\u003e (X + Y + Z) ^ 2 :: UMultiPoly 3 Int\n1 * X^2 + 2 * X * Y + 2 * X * Z + 1 * Y^2 + 2 * Y * Z + 1 * Z^2\n\n\u003e -- Laurent polynomials\n\u003e (X^-2 + 1) * (X - X^-1) :: VLaurent Integer\n1 * X + (-1) * X^-3\n\u003e (X^-1 + Y) * (X + Y^-1) :: UMultiLaurent 2 Int\n1 * X * Y + 2 + 1 * X^-1 * Y^-1\n```\n\n## Vectors\n\n`Poly v a` is polymorphic over a container `v`, implementing the `Vector` interface, and coefficients of type `a`. Usually `v` is either a boxed vector from [`Data.Vector`](https://hackage.haskell.org/package/vector/docs/Data-Vector.html) or an unboxed vector from [`Data.Vector.Unboxed`](https://hackage.haskell.org/package/vector/docs/Data-Vector-Unboxed.html). Use unboxed vectors whenever possible, e. g., when the coefficients are `Int`s or `Double`s.\n\nThere are handy type synonyms:\n\n```haskell\ntype VPoly a = Poly Data.Vector.Vector         a\ntype UPoly a = Poly Data.Vector.Unboxed.Vector a\n```\n\n## Construction\n\nThe simplest way to construct a polynomial is using the pattern `X`:\n\n```haskell\n\u003e X^2 - 3 * X + 2 :: UPoly Int\n1 * X^2 + (-3) * X + 2\n```\n\n(Unfortunately, types are often ambiguous and must be given explicitly.)\n\nWhile being convenient to read and write in REPL, `X` is relatively slow. The fastest approach is to use `toPoly`, providing it with a vector of coefficients (constant term first):\n\n```haskell\n\u003e toPoly (Data.Vector.Unboxed.fromList [2, -3, 1 :: Int])\n1 * X^2 + (-3) * X + 2\n```\n\nAlternatively one can enable `{-# LANGUAGE OverloadedLists #-}` and simply write\n\n```haskell\n\u003e [2, -3, 1] :: UPoly Int\n1 * X^2 + (-3) * X + 2\n```\n\nThere is a shortcut to construct a monomial:\n\n```haskell\n\u003e monomial 2 3.5 :: UPoly Double\n3.5 * X^2 + 0.0 * X + 0.0\n```\n\n## Operations\n\nMost operations are provided by means of instances, like `Eq` and `Num`. For example,\n\n```haskell\n\u003e (X^2 + 1) * (X^2 - 1) :: UPoly Int\n1 * X^4 + 0 * X^3 + 0 * X^2 + 0 * X + (-1)\n```\n\nOne can also find it convenient to `scale` by a monomial (cf. `monomial` above):\n\n```haskell\n\u003e scale 2 3.5 (X^2 + 1) :: UPoly Double\n3.5 * X^4 + 0.0 * X^3 + 3.5 * X^2 + 0.0 * X + 0.0\n```\n\nWhile `Poly` cannot be made an instance of `Integral` (because there is no meaningful `toInteger`),\nit is an instance of `GcdDomain` and `Euclidean` from the [`semirings`](https://hackage.haskell.org/package/semirings) package. These type classes\ncover the main functionality of `Integral`, providing division with remainder and `gcd` / `lcm`:\n\n```haskell\n\u003e Data.Euclidean.gcd (X^2 + 7 * X + 6) (X^2 - 5 * X - 6) :: UPoly Int\n1 * X + 1\n\n\u003e Data.Euclidean.quotRem (X^3 + 2) (X^2 - 1 :: UPoly Double)\n(1.0 * X + 0.0,1.0 * X + 2.0)\n```\n\nMiscellaneous utilities include `eval` for evaluation at a given point,\nand `deriv` / `integral` for taking the derivative and an indefinite integral, respectively:\n\n```haskell\n\u003e eval (X^2 + 1 :: UPoly Int) 3\n10\n\n\u003e deriv (X^3 + 3 * X) :: UPoly Double\n3.0 * X^2 + 0.0 * X + 3.0\n\n\u003e integral (3 * X^2 + 3) :: UPoly Double\n1.0 * X^3 + 0.0 * X^2 + 3.0 * X + 0.0\n```\n\n## Deconstruction\n\nUse `unPoly` to deconstruct a polynomial to a vector of coefficients (constant term first):\n\n```haskell\n\u003e unPoly (X^2 - 3 * X + 2 :: UPoly Int)\n[2,-3,1]\n```\n\nFurther, `leading` is a shortcut to obtain the leading term of a non-zero polynomial,\nexpressed as a power and a coefficient:\n\n```haskell\n\u003e leading (X^2 - 3 * X + 2 :: UPoly Double)\nJust (2,1.0)\n```\n\n## Flavours\n\n* `Data.Poly` provides dense univariate polynomials with a `Num`-based interface.\n  This is a default choice for most users.\n\n* `Data.Poly.Semiring` provides dense univariate polynomials with a `Semiring`-based interface.\n\n* `Data.Poly.Laurent` provides dense univariate Laurent polynomials with a `Semiring`-based interface.\n\n* `Data.Poly.Sparse` provides sparse univariate polynomials with a `Num`-based interface.\n  Besides that, you may find it easier to use in the REPL\n  because of a more readable `Show` instance, skipping zero coefficients.\n\n* `Data.Poly.Sparse.Semiring` provides sparse univariate polynomials with a `Semiring`-based interface.\n\n* `Data.Poly.Sparse.Laurent` provides sparse univariate Laurent polynomials with a `Semiring`-based interface.\n\n* `Data.Poly.Multi` provides sparse multivariate polynomials with a `Num`-based interface.\n\n* `Data.Poly.Multi.Semiring` provides sparse multivariate polynomials with a `Semiring`-based interface.\n\n* `Data.Poly.Multi.Laurent` provides sparse multivariate Laurent polynomials with a `Semiring`-based interface.\n\nAll flavours are available backed by boxed or unboxed vectors.\n\n## Performance\n\nAs a rough guide, `poly` is at least 20x-40x faster than the [`polynomial`](http://hackage.haskell.org/package/polynomial) library.\nMultiplication is implemented via the Karatsuba algorithm.\nHere are a couple of benchmarks for `UPoly Int`:\n\n| Benchmark                     | polynomial, μs  | poly, μs | speedup\n| :---------------------------- | --------------: | -------: | ------:\n| addition, 100 coeffs.         |              45 |       2  |  22x\n| addition, 1000 coeffs.        |             441 |      17  |  25x\n| addition, 10000 coeffs.       |            6545 |     167  |  39x\n| multiplication, 100 coeffs.   |            1733 |      33  |  52x\n| multiplication, 1000 coeffs.  |          442000 |    1456  | 303x\n\nDue to being polymorphic by multiple axis, the performance of `poly` crucially depends on specialisation of instances. Clients are strongly recommended to compile with `ghc-options: -fspecialise-aggressively` and suggested to enable `-O2`.\n\n## Additional resources\n\n* __Polynomials in Haskell__, MuniHac, 12.09.2020:\n  [slides](https://github.com/Bodigrim/my-talks/raw/master/munihac2020/slides.pdf),\n  [video](https://youtu.be/NAs3ExQZUjA).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbodigrim%2Fpoly","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbodigrim%2Fpoly","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbodigrim%2Fpoly/lists"}