{"id":13801716,"url":"https://github.com/PoslavskySV/rings","last_synced_at":"2025-05-13T11:31:53.079Z","repository":{"id":46773178,"uuid":"85172071","full_name":"PoslavskySV/rings","owner":"PoslavskySV","description":"Rings: efficient JVM library for polynomial rings","archived":false,"fork":false,"pushed_at":"2023-10-26T16:00:16.000Z","size":25949,"stargazers_count":73,"open_issues_count":15,"forks_count":10,"subscribers_count":7,"default_branch":"develop","last_synced_at":"2024-11-18T16:57:47.630Z","etag":null,"topics":["algebra","algebraic-calculations","algebraic-data-types","commutative-algebra","factorization","finite-fields","groebner-basis","mathematics","multivariate-polynomials","polynomial-arithmetic","polynomials"],"latest_commit_sha":null,"homepage":"https://rings.readthedocs.io","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/PoslavskySV.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2017-03-16T08:36:22.000Z","updated_at":"2024-10-22T11:05:33.000Z","dependencies_parsed_at":"2024-01-05T21:57:31.371Z","dependency_job_id":null,"html_url":"https://github.com/PoslavskySV/rings","commit_stats":null,"previous_names":[],"tags_count":17,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PoslavskySV%2Frings","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PoslavskySV%2Frings/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PoslavskySV%2Frings/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PoslavskySV%2Frings/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/PoslavskySV","download_url":"https://codeload.github.com/PoslavskySV/rings/tar.gz/refs/heads/develop","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253932969,"owners_count":21986486,"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":["algebra","algebraic-calculations","algebraic-data-types","commutative-algebra","factorization","finite-fields","groebner-basis","mathematics","multivariate-polynomials","polynomial-arithmetic","polynomials"],"created_at":"2024-08-04T00:01:26.259Z","updated_at":"2025-05-13T11:31:48.057Z","avatar_url":"https://github.com/PoslavskySV.png","language":"Java","funding_links":[],"categories":["Table of Contents","Science and Data Analysis"],"sub_categories":["Science and Data Analysis"],"readme":"[![image](https://img.shields.io/circleci/project/github/PoslavskySV/rings.svg?style=flat)](https://circleci.com/gh/PoslavskySV/rings)\n[![image](https://readthedocs.org/projects/rings/badge/?version=latest)](https://rings.readthedocs.io)\n[![image](http://www.javadoc.io/badge/cc.redberry/rings.svg)](http://www.javadoc.io/doc/cc.redberry/rings)\n[![image](http://www.javadoc.io/badge/cc.redberry/rings.scaladsl_2.12.svg?label=scaladoc)](http://www.javadoc.io/doc/cc.redberry/rings.scaladsl_2.12)\n[![image](https://img.shields.io/maven-central/v/cc.redberry/rings/2.svg?style=flat)](https://search.maven.org/#artifactdetails%7Ccc.redberry%7Crings%7C2.5.5%7Cjar)\n[![image](https://img.shields.io/maven-central/v/cc.redberry/rings.scaladsl_2.12/2.svg?style=flat)](https://search.maven.org/#artifactdetails%7Ccc.redberry%7Crings.scaladsl_2.12%7C2.5.5%7Cjar)\n[![image](https://img.shields.io/badge/License-Apache%202.0-blue.svg?style=flat)](https://opensource.org/licenses/Apache-2.0)\n\nRings: efficient Java/Scala library for polynomial rings\n========================================================\n\nRings is an efficient lightweight library for commutative algebra. Polynomial arithmetic, GCDs, polynomial factorization and Groebner bases are implemented with the use of modern asymptotically fast algorithms. Rings can be easily interacted or embedded in applications via simple API with fully typed hierarchy of algebraic structures and algorithms for commutative algebra. As well, an interactive REPL is also provided. The use of Scala language brings a quite novel powerful strongly typed functional programming model allowing to write short, expressive and fast code for applications. At the same time Rings shows one of the best or even unmatched in some cases performance among existing software for algebraic calculations.\n\nThe key features of Rings include:\n\n\u003e -  [Rings →](http://rings.readthedocs.io/en/latest/guide.html#ref-rings) Integers, fractions, finite and algebraic fields, multiple field extensions, polynomial rings and more\n\u003e -  [Polynomials →](http://rings.readthedocs.io/en/latest/guide.html#ref-basics-polynomials) Efficient univariate and multivariate polynomials over arbitrary coefficient rings\n\u003e -  [Polynomial GCD →](http://rings.readthedocs.io/en/latest/guide.html#ref-polynomial-methods) Highly performant polynomial GCD over arbitrary coefficient domains\n\u003e -  [Univariate and multivariate polynomial factorization →](http://rings.readthedocs.io/en/latest/guide.html#ref-multivariate-factorization) Highly performant polynomial factorization over almost arbitrary rings\n\u003e -  [Ideals and Gröbner bases →](http://rings.readthedocs.io/en/latest/guide.html#ref-ideals) Polynomial ideals and efficient algorithms for Gröbner bases\n\u003e -  [Scala DSL →](http://rings.readthedocs.io/en/latest/guide.html#ref-scala-dsl) Powerful domain specific language in Scala\n\u003e -  [Fast →](https://github.com/PoslavskySV/rings.benchmarks) Really fast library suitable for real-world computational challenges\n\nThe full documentation is available at [\u003chttp://rings.readthedocs.io\u003e](https://rings.readthedocs.io).\n\nA more academic description of the library can be found in:\n\n\u003e Stanislav Poslavsky, _Rings: An efficient Java/Scala library for polynomial rings_, Computer Physics Communications, Volume 235, 2019, Pages 400-413, [doi:10.1016/j.cpc.2018.09.005](https://doi.org/10.1016/j.cpc.2018.09.005)\n\n(please, cite this paper if you use Rings)\n\n\nSet up\n------\n\n### Interactive Rings shell and Rings scripts\n\nTo taste what Rings can do, one can try interactive session with [Ammonite REPL](http://ammonite.io). You can install Rings\u003ci\u003e.repl\u003c/i\u003e with Homebrew:\n\n``` bash\n$ brew install PoslavskySV/rings/rings.repl\n```\n\nor just by typing the following commands at the prompt:\n\n``` bash\n$ sudo sh -c '(echo \"#!/usr/bin/env sh\" \u0026\u0026 curl -L https://github.com/lihaoyi/Ammonite/releases/download/1.1.2/2.12-1.1.2) \u003e /usr/local/bin/amm \u0026\u0026 chmod +x /usr/local/bin/amm'\n$ sudo sh -c 'curl -L -o /usr/local/bin/rings.repl https://git.io/vd7EY \u0026\u0026 chmod +x /usr/local/bin/rings.repl'\n```\n\nNow run Rings\u003ci\u003e.repl\u003c/i\u003e:\n\n``` scala\n$ rings.repl\nLoading...\nRings 2.5.5: efficient Java/Scala library for polynomial rings\n\n@ implicit val ring = MultivariateRing(Z, Array(\"x\", \"y\", \"z\"))\nring: MultivariateRing[IntZ] = MultivariateRing(Z, Array(\"x\", \"y\", \"z\"), LEX)\n\n@ val poly1 = ring(\"x + y - z\").pow(8) \npoly1: MultivariatePolynomial[IntZ] = z^8-8*y*z^7+28*y^2*z^6-56*y^3*z^5+70*...\n\n@ val poly2 = ring(\"x - y + z\").pow(8) \npoly1: MultivariatePolynomial[IntZ] = z^8-8*y*z^7+28*y^2*z^6-56*y^3*z^5+70*...\n\n@ Factor(poly1 - poly2)\nres13: FactorDecomposition[MultivariatePolynomial[IntZ]] = \n       16*(x)*((-1)*z+y)\n       *(z^4-4*y*z^3+6*y^2*z^2-4*y^3*z+y^4+6*x^2*z^2-12*x^2*y*z+6*x^2*y^2+x^4)\n       *(z^2-2*y*z+y^2+x^2)\n```\n\nAdditionally, Rings\u003ci\u003e.repl\u003c/i\u003e can be used to run scripts with Rings code:\n\n```\n$ rings.repl myRingsScript.sc\n```\n\n### Java/Scala library\n\nRings is currently available for Java and Scala. To get started with Scala SBT, simply add the following dependence to your `build.sbt` file:\n\n``` scala\nlibraryDependencies += \"cc.redberry\" %% \"rings.scaladsl\" % \"2.5.5\"\n```\n\nFor using Rings solely in Java there is Maven artifact:\n\n``` scala\n\u003cdependency\u003e\n    \u003cgroupId\u003ecc.redberry\u003c/groupId\u003e\n    \u003cartifactId\u003erings\u003c/artifactId\u003e\n    \u003cversion\u003e2.5.5\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\n### Development version\n\nDownload latest Rings from the develop:\n```bash\ngit clone https://github.com/PoslavskySV/rings.git\ncd rings\n```\n\nInstall Java artifact locally:\n```bash\ncd rings\nmvn install -DskipTests\n```\n\nInstall Rings.scaladsl locally:\n```bash\ncd rings.scaladsl\nsbt publishLocal\n```\n\nTo run a simple REPL run e.g.:\n```bash\ncd rings.scaladsl\nsbt console\n```\n\n```scala\n@\nimport cc.redberry.rings\nimport cc.redberry.rings.primes.{SmallPrimes, BigPrimes}\nimport rings.{bigint, primes, linear, poly}\nimport poly.{univar, multivar}\nimport poly.PolynomialMethods._\nimport multivar.MonomialOrder._\nimport multivar.GroebnerMethods\nimport rings.scaladsl._\nimport util._\nimport syntax._\n\n@ implicit val ring = MultivariateRing(Z, Array(\"x\", \"y\", \"z\"))\nring: MultivariateRing[IntZ] = MultivariateRing(Z, Array(\"x\", \"y\", \"z\"), LEX)\n\n@ val poly1 = ring(\"x + y - z\").pow(8) \npoly1: MultivariatePolynomial[IntZ] = z^8-8*y*z^7+28*y^2*z^6-56*y^3*z^5+70*...\n\n@ val poly2 = ring(\"x - y + z\").pow(8) \npoly1: MultivariatePolynomial[IntZ] = z^8-8*y*z^7+28*y^2*z^6-56*y^3*z^5+70*...\n\n@ Factor(poly1 - poly2)\nres13: FactorDecomposition[MultivariatePolynomial[IntZ]] = \n       16*(x)*((-1)*z+y)\n       *(z^4-4*y*z^3+6*y^2*z^2-4*y^3*z+y^4+6*x^2*z^2-12*x^2*y*z+6*x^2*y^2+x^4)\n       *(z^2-2*y*z+y^2+x^2)\n```\n\n\n\nExamples: rings, ideals, Gröbner bases, GCDs \u0026 factorization\n-------------------------------------------------------------\n\nBelow examples can be evaluated directly in the Rings\u003ci\u003e.repl\u003c/i\u003e. If using Rings in Scala, the following preambula will import all required things from Rings library:\n\n``` scala\nimport cc.redberry.rings\n\nimport rings.poly.PolynomialMethods._\nimport rings.scaladsl._\nimport syntax._\n```\n\nJava examples can be found in the [complete documentation pages](https://rings.readthedocs.io).\n\n------------------------------------------------------------------------\n\n### Some built-in rings\n\n\nPolynomial rings over *Z* and *Q*:\n\n``` scala\n// Ring Z[x]\nUnivariateRing(Z, \"x\")\n// Ring Z[x, y, z]\nMultivariateRing(Z, Array(\"x\", \"y\", \"z\"))\n// Ring Q[a, b, c]\nMultivariateRing(Q, Array(\"a\", \"b\", \"c\"))\n```\n\nPolynomial rings over *Z_p*:\n\n``` scala\n// Ring Z/3[x]\nUnivariateRingZp64(3, \"x\")\n// Ring Z/3[x, y, z]\nMultivariateRingZp64(3, Array(\"x\", \"y\", \"z\"))\n// Ring Z/p[x, y, z] with p = 2^107 - 1 (Mersenne prime)\nMultivariateRing(Zp(Z(2).pow(107) - 1), Array(\"x\", \"y\", \"z\"))\n```\n\nGalois fields:\n\n``` scala\n// Galois field with cardinality 7^10 \n// (irreducible polynomial will be generated automatically)\nGF(7, 10, \"x\")\n// GF(7^3) generated by irreducible polynomial \"1 + 3*z + z^2 + z^3\"\nGF(UnivariateRingZp64(7, \"z\")(\"1 + 3*z + z^2 + z^3\"), \"z\")\n```\n\nFields of rational functions:\n\n``` scala\n// Field of fractions of univariate polynomials Z[x]\nFrac(UnivariateRing(Z, \"x\"))\n// Field of fractions of multivariate polynomials Z/19[x, y, z]\nFrac(MultivariateRingZp64(19, Array(\"x\", \"y\", \"z\")))\n```\n\n### Univariate polynomials\n\nSome algebra in Galois field *GF(17,9)*:\n\n``` scala\n// Galois field GF(17, 9) with irreducible \n// poly in Z/17[t] generated automaticaly\nimplicit val ring = GF(17, 9, \"t\")\n\n// pick some random field element\nval a = ring.randomElement()\n// raise field element to the power of 1000\nval b = a.pow(1000)\n// reciprocal of field element\nval c = 1 / b\n\nassert ( b * c === 1)\n\n// explicitly parse field element from string:\n// input poly will be automatically converted to\n// element of GF(17, 9) (reduced modulo field generator)\nval d = ring(\"1 + t + t^2 + t^3 + 15 * t^999\")\n// do some arbitrary math ops in the field\nval some = a / (b + c) + a.pow(6) - a * b * c * d\n```\n\n------------------------------------------------------------------------\n\nExtended GCD in *Z_{17}[x]*:\n\n``` scala\n// polynomial ring Z/17[x]\nimplicit val ring = UnivariateRingZp64(17, \"x\")\n// parse ring element\nval x = ring(\"x\")\n\n// construct some polynomials\nval poly1 = 1 + x + x.pow(2) + x.pow(3)\nval poly2 = 1 + 2 * x + 9 * x.pow(2)\n\n// compute (gcd, s, t) such that s * poly1 + t * poly2 = gcd\nval Array(gcd, s, t) = PolynomialExtendedGCD(poly1, poly2)\nassert (s * poly1 + t * poly2 == gcd)\n\nprintln((gcd, s, t))\n```\n\n------------------------------------------------------------------------\n\nFactor polynomial in *Z_{17}[x]*:\n\n``` scala\n// polynomial ring Z/17[x]\nimplicit val ring = UnivariateRingZp64(17, \"x\")x\n\n// parse polynomial from string\nval poly = ring(\"4 + 8*x + 12*x^2 + 5*x^5 - x^6 + 10*x^7 + x^8\")\n\n// factorize poly\nval factors = Factor(poly)\n\nprintln(factors)\n```\n\nCoefficient rings with arbitrary large characteristic are available:\n\n\n``` scala\n// coefficient ring Z/1237940039285380274899124357 (the next prime to 2^100)\nval modulus = Z(\"1267650600228229401496703205653\")\nval cfRing  = Zp(modulus)\n\n// ring Z/1237940039285380274899124357[x]\nimplicit val ring = UnivariateRing(cfRing, \"x\")\nval poly = ring(\"4 + 8*x + 12*x^2 + 5*x^5 + 16*x^6 + 27*x^7 + 18*x^8\")\n\n// factorize poly\nprintln(Factor(poly))\n```\n\n(large primes can be generated with `BigPrimes.nextPrime` method, see [Prime numbers](http://rings.readthedocs.io/en/latest/guide.html#ref-primes)).\n\n\n------------------------------------------------------------------------\n\nRing of univariate polynomials over elements of Galois field *GF(7,3)[x]*:\n\n``` scala\n// elements of coefficient field GF(7,3) are represented as polynomials\n// over \"z\" modulo irreducible polynomial \"1 + 3*z + z^2 + z^3\"\nval cfRing = GF(UnivariateRingZp64(7, \"z\")(\"1 + 3*z + z^2 + z^3\"), \"z\")\n\nassert(cfRing.characteristic().intValue() == 7)\nassert(cfRing.cardinality().intValue() == 343)\n\n// polynomial ring GF(7^3)[x]\nimplicit val ring = UnivariateRing(cfRing, \"x\")\n\n// parse poly in GF(7^3)[x] from string\n// coefficients of polynomials in GF(7,3)[x] are elements\n// of GF(7,3) that is polynomials over \"z\"\nval poly = ring(\"1 - (1 - z^3) * x^6 + (1 - 2*z) * x^33 + x^66\")\n\n// factorize poly\nval factors = Factor(poly)\nprintln(s\"${ring show factors}\")\n```\n\n### Multivariate polynomials\n\nSome math with multivariate polynomials from *Z[x, y, z]*:\n\n``` scala\n// ring Z[x, y, z]\nimplicit val ring = MultivariateRing(Z, Array(\"x\", \"y\", \"z\")) \n// parse some ring elements\nval (x, y, z) = ring(\"x\", \"y\", \"z\") \n\n// construct some polynomials using different math ops\nval a = (x + y + z).pow(2) - 1 \nval b = (x - y - z - 1).pow(2) + x + y + z - 1 \nval c = (a + b + 1).pow(9) - a - b - 1\n\n// reduce c modulo a and b (multivariate division with remainder)\nval (div1, div2, rem) = c /%/% (a, b)\n```\n\n------------------------------------------------------------------------\n\nMultivariate GCD in *Z[a, b, c]*:\n\n``` scala\n// ring Z[a, b, c]\nimplicit val ring = MultivariateRing(Z, Array(\"a\", \"b\", \"c\"))\n\n// parse polynomials from strings\nval poly1 = ring(\"-b-b*c-b^2+a+a*c+a^2\")\nval poly2 = ring(\"b^2+b^2*c+b^3+a*b^2+a^2+a^2*c+a^2*b+a^3\")\n\n// compute multivariate GCD\nval gcd   = PolynomialGCD(poly1, poly2)\nassert (poly1 % gcd === 0)\nassert (poly2 % gcd === 0)\nprintln(gcd)\n```\n\n------------------------------------------------------------------------\n\nFactor polynomial in *Z_{2}[x, y, z]*:\n\n``` scala\n// ring Z/2[x, y, z]\nimplicit val ring = MultivariateRingZp64(2, Array(\"x\", \"y\", \"z\"))\nval (x, y, z) = ring(\"x\", \"y\", \"z\")\n\n// factorize poly\nval factors = Factor(1 + (1 + x + y + z).pow(2) + (x + y + z).pow(4))\nprintln(factors)\n```\n\n------------------------------------------------------------------------\n\nFactor polynomial in *Z[a, b, c]*:\n\n``` scala\n// ring Z[a, b, c]\nimplicit val ring = MultivariateRing(Z, Array(\"a\", \"b\", \"c\"))\nval (a, b, c) = ring(\"a\", \"b\", \"c\")\n\n// factorize poly\nval factors = Factor(1 - (1 + a + b + c).pow(2) - (2 + a + b + c).pow(3))\nprintln(ring show factors)\n```\n\n------------------------------------------------------------------------\n\nFactor polynomial in *Q[x, y, z]*:\n\n``` scala\n// ring Q[x, y, z]\nimplicit val ring = MultivariateRing(Q, Array(\"x\", \"y\", \"z\"))\n\n// parse some poly from string\nval poly = ring(\n  \"\"\"\n    |(1/6)*y*z + (1/6)*y^3*z^2 - (1/2)*y^6*z^5 - (1/2)*y^8*z^6\n    |-(1/3)*x*z - (1/3)*x*y^2*z^2 + x*y^5*z^5 + x*y^7*z^6\n    |+(1/9)*x^2*y^2*z - (1/3)*x^2*y^7*z^5 - (2/9)*x^3*y*z\n    |+(2/3)*x^3*y^6*z^5 - (1/2)*x^6*y - (1/2)*x^6*y^3*z\n    |+x^7 + x^7*y^2*z - (1/3)*x^8*y^2 + (2/3)*x^9*y\n  \"\"\".stripMargin)\n\n// factorize poly\nval factors = Factor(poly)\nprintln(factors)\n```\n\n------------------------------------------------------------------------\n\nRing of multivariate polynomials over elements of Galois field *GF(7,3)[x, y, z]*:\n\n``` scala\n// elements of GF(7,3) are represented as polynomials\n// over \"z\" modulo irreducible polynomial \"1 + 3*z + z^2 + z^3\"\nval cfRing = GF(UnivariateRingZp64(7, \"z\")(\"1 + 3*z + z^2 + z^3\"), \"z\")\n// ring GF(7,3)[a,b,c]\nimplicit val ring = MultivariateRing(cfRing, Array(\"a\", \"b\", \"c\"))\n\n// parse poly in GF(7^3)[a,b,c] from string\n// coefficients of polynomials in GF(7,3)[a,b,c] are elements\n// of GF(7,3) that is polynomials over \"z\"\nval poly = ring(\"1 - (1 - z^3) * a^6*b + (1 - 2*z) * c^33 + a^66\")\n\n//factorize poly\nprintln(Factor(poly))\n```\n\n\n\n### Rational function arithmetic\n\nDefine a field of rational functions *Frac(Z[x,y,z])* and input some functions:\n\n``` scala\n// Frac(Z[x,y,z])\nimplicit val field = Frac(MultivariateRing(Z, Array(\"x\", \"y\", \"z\")))\n\n// parse some math expression from string\n// it will be automatically reduced to a common denominator\n// with the gcd being automatically cancelled\nval expr1 = field(\"(x/y/(x - z) + (x + z)/(y - z))^2 - 1\")\n\n// do some math ops programmatically\nval (x, y, z) = field(\"x\", \"y\", \"z\")\nval expr2 = expr1.pow(2) + x / y - z\n```\n\nGreatest common divisors of numerators and denominators are always cancelled automatically. \n\nUse ``Coder`` to parse more complicated expressions:\n\n``` scala\n// bind expr1 and expr2 to variables to use them further in parser\nfield.coder.bind(\"expr1\", expr1)\nfield.coder.bind(\"expr2\", expr2)\n\n// parse some complicated expression from string\n// it will be automatically reduced to a common denominator\n// with the gcd being automatically cancelled\nval expr3 = field(\n  \"\"\"\n     expr1 / expr2 - (x*y - z)/(x-y)/expr1\n     + x / expr2 - (x*z - y)/(x-y)/expr1/expr2\n     + x^2*y^2 - z^3 * (x - y)^2\n  \"\"\")\n\n// export expression to string\nprintln(field.stringify(expr3))\n\n// take numerator and denominator\nval num = expr3.numerator()\nval den = expr3.denominator()\n// common GCD is always cancelled automatically\nassert( field.ring.gcd(num, den).isOne )\n```\n\nCompute unique factor decomposition of rational function:\n\n``` scala\n// compute unique factor decomposition of expression\nval factors = field.factor(expr3)\nprintln(field.stringify(factors))\n```\n\n### Ideals and Groebner bases\n\nConstruct some ideal and check its properties:\n\n``` scala\n// ring Z/17[x,y,z]\nimplicit val ring = MultivariateRingZp64(17, Array(\"x\", \"y\", \"z\"))\nval (x, y, z) = ring(\"x\", \"y\", \"z\")\n\n// create ideal with two generators using GREVLEX monomial order for underlying Groebner basis\nval I = Ideal(ring, Seq(x.pow(2) + y.pow(12) - z, x.pow(2) * z + y.pow(2) - 1), GREVLEX)\n// I is proper ideal\nassert(I.isProper)\n\n// get computed Groebner basis\nval gb = I.groebnerBasis\nprintln(gb)\n\n// check some ideal properties\nassert(I.dimension == 1)\nassert(I.degree == 36)\n```\n\nUnions, intersections and quotients of ideals:\n\n``` scala\n// create another ideal with only one generator\nval J = Ideal(ring, Seq(x.pow(4) * y.pow(4) + 1), GREVLEX)\n// J is principal ideal\nassert(J.isPrincipal)\n\nval union = I union J\n// union is zero dimensional ideal\nassert(union.dimension == 0)\n\nval intersection = I intersection J\n// intersection is still 2-dimensional\nassert(intersection.dimension == 2)\n\n// yet another ideal\nval K = Ideal(ring, Seq(z * x.pow(4) - z * y.pow(14) + y * z.pow(16), (x + y + z).pow(4)), GREVLEX)\n// compute complicated quotient ideal\nval quotient = (I * J * K) :/ times\nassert(quotient == K) \n```\n\n\n------------------------------------------------------------------------\n\nConstruct lexicographic Gröbner basis to solve a system of equations:\n\n``` scala\n// ring Q[a, b, c]\nimplicit val ring = MultivariateRing(Q, Array(\"x\", \"y\", \"z\"))\n\n// parse some polynomials from strings\nval a = ring(\"8*x^2*y^2 + 5*x*y^3 + 3*x^3*z + x^2*y*z\")\nval b = ring(\"x^5 + 2*y^3*z^2 + 13*y^2*z^3 + 5*y*z^4\")\nval c = ring(\"8*x^3 + 12*y^3 + x*z^2 + 3\")\nval d = ring(\"7*x^2*y^4 + 18*x*y^3*z^2 + y^3*z^3\")\n\n// construct ideal with Groebner basis in LEX order\nval ideal = Ideal(ring, Seq(a, b, c, d), LEX)\n// it is very simple: \u003cz^2, x, 1+4*y^3\u003e\nprintln(ideal)\n```\n\n\n### Programming\n\nImplement generic function for solving linear Diophantine equations:\n\n``` scala\n/**\n  * Solves equation \\sum f_i s_i  = gcd(f_1, \\dots, f_N) for given f_i and unknown s_i\n  * @return a tuple (gcd, solution)\n  */\ndef solveDiophantine[E](fi: Seq[E])(implicit ring: Ring[E]) =\n  fi.foldLeft((ring(0), Seq.empty[E])) { case ((gcd, seq), f) =\u003e\n    val xgcd = ring.extendedGCD(gcd, f)\n    (xgcd(0), seq.map(_ * xgcd(1)) :+ xgcd(2))\n  }\n```\n\nImplement generic function for computing partial fraction decomposition:\n\n``` scala\n/** Computes partial fraction decomposition of given rational */\ndef apart[E](frac: Rational[E]) = {\n  implicit val ring: Ring[E] = frac.ring\n  val factors = ring.factor(frac.denominator).map {case (f, exp) =\u003e f.pow(exp)}\n  val (gcd,  nums) = solveDiophantine(factors.map(frac.denominator / _))\n  val (ints, rats) = (nums zip factors)\n    .map { case (num, den) =\u003e Rational(frac.numerator * num, den * gcd) }\n    .flatMap(_.normal)       // extract integral parts from fractions\n    .partition(_.isIntegral) // separate integrals and fractions\n  rats :+ ints.foldLeft(Rational(ring(0)))(_ + _)\n}\n```\n\nApply that function to elements of different rings:\n\n``` scala\n// partial fraction decomposition for rationals\n// gives List(184/479, (-10)/13, 1/8, (-10)/47, 1)\nval qFracs = apart( Q(\"1234213 / 2341352\"))\n\n// partial fraction decomposition for rational functions\nval ufRing = Frac(UnivariateRingZp64(17, \"x\"))\n// gives List(4/(16+x), 1/(10+x), 15/(1+x), (14*x)/(15+7*x+x^2))\nval pFracs = apart( ufRing(\"1 / (3 - 3*x^2 - x^3 + x^5)\") )\n```\n\n------------------------------------------------------------------------\n\nImplement Lagrange method for univariate interpolation:\n\n```latex\n    p(x) = \\sum_i p(x_i) \\Pi_{j \\ne i} \\frac{x_{\\phantom{i}} - x_j}{x_i -x_j}\n```\n\n``` scala\n/** Lagrange polynomial interpolation formula */\ndef interpolate[Poly \u003c: IUnivariatePolynomial[Poly], Coef]\n    (points: Seq[(Coef, Coef)])\n    (implicit ring: IUnivariateRing[Poly, Coef]) = {\n      // implicit coefficient ring (setups algebraic operators on type Coef)\n      implicit val cfRing: Ring[Coef] = ring.cfRing\n      if (!cfRing.isField) throw new IllegalArgumentException\n      points.indices\n        .foldLeft(ring(0)) { case (sum, i) =\u003e\n          sum + points.indices\n            .filter(_ != i)\n            .foldLeft(ring(points(i)._2)) { case (product, j) =\u003e\n              product * (ring.`x` - points(j)._1) / (points(i)._1 - points(j)._1)\n            }\n        }\n    }\n```\n\nInterpolate polynomial from *Frac(Z_{13}[a,b,c])[x]*:\n\n``` scala\n// coefficient ring Frac(Z/13[a,b,c])\nval cfRing = Frac(MultivariateRingZp64(2, Array(\"a\", \"b\", \"c\")))\nval (a, b, c) = cfRing(\"a\", \"b\", \"c\")\n\nimplicit val ring = UnivariateRing(cfRing, \"x\")\n// interpolate with Lagrange formula\nval data = Seq(a -\u003e b, b -\u003e c, c -\u003e a)\nval poly = interpolate(data)\nassert(data.forall { case (p, v) =\u003e poly.eval(p) == v })\n```\n\n\nHighlighted benchmarks\n----------------------\n\n\u003cimg src=\"https://github.com/PoslavskySV/rings/blob/develop/doc/_static/gcd_nvars.png?raw=true\" width=\"600\"\u003e\n\nDependence of multivariate GCD performance on the number of variables. For details see [benchmarks](https://github.com/PoslavskySV/rings.benchmarks/tree/master/gcd)\n\n\u003cimg src=\"https://github.com/PoslavskySV/rings/blob/develop/doc/_static/gcd_size.png?raw=true\" width=\"600\"\u003e\n\nDependence of multivariate GCD performance on the size of input polynomials. For details see [benchmarks](https://github.com/PoslavskySV/rings.benchmarks/tree/master/gcd)\n\n\u003cimg src=\"https://github.com/PoslavskySV/rings/blob/develop/doc/_static/factor.png?raw=true\" width=\"600\"\u003e\n\nDependence of multivariate factorization performance on the number of variables. For details see [benchmarks](https://github.com/PoslavskySV/rings.benchmarks/tree/master/factor)\n\n\u003cimg src=\"https://github.com/PoslavskySV/rings/blob/develop/doc/_static/factor_univar.png?raw=true\" width=\"600\"\u003e\n\nUnivariate factorization performance on polynomials of the form *(1 + \\sum_{i = 1}^{i \\leq deg} i \\times x^i)* in *Z_{17}[x]*.\n\n\nIndex of algorithms implemented in Rings\n----------------------------------------\n\nThe list of algorithms implemented in Rings (and references to the literature) can be found at [Rings RTD page](http://rings.readthedocs.io/en/latest/algorithms.html)\n\n\n------------------------------------------------------------------------\n\nLicense\n-------\n\nApache License, Version 2.0 \u003chttp://www.apache.org/licenses/LICENSE-2\u003e.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FPoslavskySV%2Frings","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FPoslavskySV%2Frings","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FPoslavskySV%2Frings/lists"}