{"id":15010981,"url":"https://github.com/stla/hspray","last_synced_at":"2025-12-27T10:11:16.418Z","repository":{"id":64625709,"uuid":"576764117","full_name":"stla/hspray","owner":"stla","description":"Multivariate polynomials and fractions of multivariate polynomials.","archived":false,"fork":false,"pushed_at":"2024-06-19T19:47:20.000Z","size":490,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-12-08T04:20:08.451Z","etag":null,"topics":["haskell","multivariate-polynomials","polynomials","rational-functions"],"latest_commit_sha":null,"homepage":"","language":"Haskell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/stla.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}},"created_at":"2022-12-10T22:38:04.000Z","updated_at":"2024-12-22T02:54:35.000Z","dependencies_parsed_at":"2023-01-27T13:01:21.146Z","dependency_job_id":"f3f374ad-f5a8-47b4-bf76-2128315a99fe","html_url":"https://github.com/stla/hspray","commit_stats":{"total_commits":34,"total_committers":1,"mean_commits":34.0,"dds":0.0,"last_synced_commit":"926f7508773e92bc76a7266a01a9327d6947a7d6"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/stla/hspray","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stla%2Fhspray","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stla%2Fhspray/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stla%2Fhspray/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stla%2Fhspray/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/stla","download_url":"https://codeload.github.com/stla/hspray/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stla%2Fhspray/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28077395,"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-12-27T02:00:05.897Z","response_time":58,"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":["haskell","multivariate-polynomials","polynomials","rational-functions"],"created_at":"2024-09-24T19:38:02.780Z","updated_at":"2025-12-27T10:11:16.398Z","avatar_url":"https://github.com/stla.png","language":"Haskell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# hspray\n\n\u003c!-- badges: start --\u003e\n[![Stack-lts](https://github.com/stla/hspray/actions/workflows/Stack-lts.yml/badge.svg)](https://github.com/stla/hspray/actions/workflows/Stack-lts.yml)\n[![Stack-nightly](https://github.com/stla/hspray/actions/workflows/Stack-nightly.yml/badge.svg)](https://github.com/stla/hspray/actions/workflows/Stack-nightly.yml)\n\u003c!-- badges: end --\u003e\n\n***Simple multivariate polynomials in Haskell.*** \nThis package deals with multivariate polynomials over a commutative ring, \nfractions of multivariate polynomials over a commutative field, and \nmultivariate polynomials with symbolic parameters in their coefficients.\n\n____\n\nThe main type provided by this package is `Spray a`. \nAn object of type `Spray a` represents a multivariate polynomial whose\ncoefficients are represented by the objects of type `a`. For example:\n\n```haskell\nimport Math.Algebra.Hspray\nx = lone 1 :: Spray Double\ny = lone 2 :: Spray Double\nz = lone 3 :: Spray Double\npoly = (2 *^ (x^**^3 ^*^ y ^*^ z) ^+^ x^**^2) ^*^ (4 *^ (x ^*^ y ^*^ z))\nputStrLn $ prettyNumSpray poly\n-- 8.0*x^4.y^2.z^2 + 4.0*x^3.y.z\n```\n\nThis is the easiest way to construct a spray: first introduce the polynomial \nvariables with the `lone` function, and then combine them with arithmetic \noperations.\n\nThere are numerous functions to print a spray. If you don't like the letters \n`x`, `y`, `z` in the output of `prettyNumSpray`, you can use `prettyNumSprayXYZ` \nto change them to whatever you want:\n\n```haskell\nputStrLn $ prettyNumSprayXYZ [\"A\",\"B\",\"C\"] poly\n-- 8.0*A^4.B^2.C^2 + 4.0*A^3.B.C\n```\n\nNote that this function does not throw an error if you don't provide enough \nletters; in such a situation, it takes the first given letter and it appends \nit with the digit `i` to denote the `i`-th variable: \n\n```haskell\nputStrLn $ prettyNumSprayXYZ [\"A\",\"B\"] poly\n-- 8.0*A1^4.A2^2.A3^2 + 4.0*A1^3.A2.A3\n```\n\nThis is the same output as the one of `prettyNumSprayX1X2X3 \"A\" poly`.\n\nMore generally, one can use the type `Spray a` as long as the type `a` has \nthe instances `Eq` and `Algebra.Ring` (defined in the **numeric-prelude** \nlibrary). For example `a = Rational`:\n\n```haskell\nimport Math.Algebra.Hspray\nimport Data.Ratio\nx = lone 1 :: QSpray -- QSpray = Spray Rational\ny = lone 2 :: QSpray \nz = lone 3 :: QSpray\npoly = ((2%3) *^ (x^**^3 ^*^ y ^*^ z) ^-^ x^**^2) ^*^ ((7%4) *^ (x ^*^ y ^*^ z))\nputStrLn $ prettyQSpray poly\n-- (7/6)*x^4.y^2.z^2 - (7/4)*x^3.y.z\n```\n\nOr `a = Spray Double`:\n\n```haskell\nimport Math.Algebra.Hspray\nalpha = lone 1 :: Spray Double\nx = lone 1 :: Spray (Spray Double)\ny = lone 2 :: Spray (Spray Double)\npoly = ((alpha *^ x) ^+^ (alpha *^ y))^**^2  \nshowSprayXYZ' (prettyNumSprayXYZ [\"alpha\"]) [\"x\",\"y\"] poly\n-- (alpha^2)*x^2 + (2.0*alpha^2)*x.y + (alpha^2)*y^2\n```\n\nWe will come back to these sprays of type `Spray (Spray a)`. They can \nbe used to represent parametric polynomials.\n\n\n#### Evaluation of a spray:\n\n```haskell\nimport Math.Algebra.Hspray\nx = lone 1 :: Spray Double\ny = lone 2 :: Spray Double\nz = lone 3 :: Spray Double\nspray = 2 *^ (x ^*^ y ^*^ z) \n-- evaluate spray at x=2, y=1, z=2\nevalSpray spray [2, 1, 2]\n-- 8.0\n```\n\n#### Partial evaluation:\n\n```haskell\nimport Math.Algebra.Hspray\nimport Data.Ratio\nx1 = lone 1 :: Spray Rational\nx2 = lone 2 :: Spray Rational\nx3 = lone 3 :: Spray Rational\nspray = x1^**^2 ^+^ x2 ^+^ x3 ^-^ unitSpray\nputStrLn $ prettyQSprayX1X2X3 \"x\" spray\n-- x1^2 + x2 + x3 - 1\n--\n-- substitute x1 -\u003e 2 and x3 -\u003e 3, and don't substitute x2\nspray' = substituteSpray [Just 2, Nothing, Just 3] spray\nputStrLn $ prettyQSprayX1X2X3 \"x\" spray'\n-- x2 + 6\n```\n\n#### Differentiation of a spray:\n\n```haskell\nimport Math.Algebra.Hspray\nx = lone 1 :: Spray Double\ny = lone 2 :: Spray Double\nz = lone 3 :: Spray Double\nspray = 2 *^ (x ^*^ y ^*^ z) ^+^ (3 *^ x^**^2)\nputStrLn $ prettyNumSpray spray\n-- 3.0*x^2 + 2.0*x.y.z\n--\n-- derivative with respect to x\nputStrLn $ prettyNumSpray $ derivative 1 spray\n-- 6.0*x + 2.0*y.z\"\n```\n\n## Gröbner bases\n\nAs of version 2.0.0, it is possible to compute a Gröbner basis of the ideal \ngenerated by a list of spray polynomials.\n\nOne of the numerous applications of Gröbner bases is the *implicitization* \nof a system of parametric equations. That means that they allow to get an \nimplicit equation equivalent to a given set of parametric equations, for \nexample an implicit equation of a parametrically defined surface. Let us give \nan example of implicitization for an *Enneper surface*. Here are the parametric\nequations of this surface:\n\n```haskell\nimport Math.Algebra.Hspray\nimport Data.Ratio ( (%) )\nu = qlone 1\nv = qlone 2\nx = 3*^u ^+^ 3*^(u ^*^ v^**^2) ^-^ u^**^3\ny = 3*^v ^+^ 3*^(u^**^2 ^*^ v) ^-^ v^**^3\nz = 3*^u^**^2 ^-^ 3*^v^**^2\n```\n\nThe first step of the implicitization is to compute a Gröbner basis of the \nfollowing list of polynomials:\n\n```haskell\ngenerators = [x ^-^ qlone 3, y ^-^ qlone 4, z ^-^ qlone 5]\n```\n\nOnce the Gröbner basis is obtained, one has to identify which of its elements \ndo not involve the first two variables (`u` and `v`):\n\n```haskell\ngbasis = groebnerBasis generators True\nisFreeOfUV :: QSpray -\u003e Bool\nisFreeOfUV p = not (involvesVariable p 1) \u0026\u0026 not (involvesVariable p 2)\nfreeOfUV = filter isFreeOfUV gbasis\n```\n\nThen the implicit equations (there can be several ones) are obtained by \nremoving the first two variables from these elements:\n\n```haskell\nresults = map (dropVariables 2) freeOfUV \n```\n\nHere we find only one implicit equation (i.e. `length results` is `1`). \nWe only partially display it because it is long:\n\n```haskell\nimplicitEquation = results !! 0\nputStrLn $ prettyQSpray implicitEquation\n-- x^6 - 3*x^4.y^2 + (5/9)*x^4.z^3 + 6*x^4.z^2 - 3*x^4.z + 3*x^2.y^4 + ...\n```\n\nLet us check it is correct. We take a point on the Enneper surface, for \nexample the point corresponding to $u=1/4$ and $v=2/3$ ($u$ and $v$ range \nfrom $0$ to $1$):\n\n```haskell\nxyz = map (evaluateAt [1%4, 2%3]) [x, y, z]\n```\n\nIf the implicitization is correct, then the polynomial `implicitEquation` \nshould be zero at any point on the Enneper surface. This is true for our point:\n\n```haskell\nevaluateAt xyz implicitEquation == 0\n-- True\n```\n\nIn the [unit tests](https://github.com/stla/hspray/blob/main/tests/Main.hs), \nyou will find a more complex example of implicitization: the implicitization \nof the ellipse parametrically defined by $x = a \\cos t$ and $y = b \\sin t$. \nIt is more complex because there are the parameters $a$ and $b$ and because \none has to use the relation ${(\\cos t)}^2 + {(\\sin t)}^2 = 1$.\n\n\n## Easier usage \n\nTo construct a spray using the ordinary symbols `+`, `-`, `*` and `^`, \none can hide these operators from **Prelude** and import them from the \n**numeric-prelude** library; constructing a spray in this context is easier:\n\n```haskell\nimport Prelude hiding ((+), (-), (*), (^), (*\u003e), (\u003c*))\nimport qualified Prelude as P\nimport Algebra.Additive              \nimport Algebra.Module                \nimport Algebra.Ring                  \nimport Math.Algebra.Hspray\nimport Data.Ratio\nx = lone 1 :: QSpray \ny = lone 2 :: QSpray \nz = lone 3 :: QSpray\nspray  = ((2%3) *^ (x^**^3 ^*^ y ^*^ z) ^-^ x^**^2) ^*^ ((7%4) *^ (x ^*^ y ^*^ z))\nspray' = ((2%3) *^ (x^3 * y * z) - x^2) * ((7%4) *^ (x * y * z))\nspray == spray'\n-- True\n```\n\nNote that `*\u003e` could be used instead of `*^` but running `lambda *\u003e spray` \npossibly throws an \"ambiguous type\" error regarding the type of `lambda`.\n\nMaybe better (I didn't try yet), follow the \"Usage\" section on the \n[Hackage page](https://hackage.haskell.org/package/numeric-prelude-0.4.4#usage) \nof **numeric-prelude**.\n\n\n## Symbolic parameters in the coefficients\n\nAssume you have the polynomial `a * (x² + y²) + 2b/3 * z`, \nwhere `a` and `b` are symbolic rational numbers. You can represent this \npolynomial by a `Spray (Spray Rational)` spray as follows:\n\n```haskell\nimport Prelude hiding ((*), (+), (-), (^))\nimport qualified Prelude as P\nimport Algebra.Additive              \nimport Algebra.Ring                  \nimport Math.Algebra.Hspray\n\nx = lone 1 :: Spray (Spray Rational)\ny = lone 2 :: Spray (Spray Rational)\nz = lone 3 :: Spray (Spray Rational)\na = lone 1 :: Spray Rational\nb = lone 2 :: Spray Rational\n\nspray = a *^ (x^2 + y^2) + ((2 *^ b) /^ 3) *^ z \nputStrLn $ \n  showSprayXYZ' (prettyQSprayXYZ [\"a\",\"b\"]) [\"X\",\"Y\",\"Z\"] spray\n-- (a)*X^2 + (a)*Y^2 + ((2/3)*b)*Z\n```\n\nYou can extract the powers and the coefficients as follows:\n\n```haskell\nl = toList spray\nmap fst l\n-- [[0,0,1],[2],[0,2]]\nmap toList $ map snd l\n-- [[([0,1],2 % 3)],[([1],1 % 1)],[([1],1 % 1)]]\n```\n\nThese `Spray (Spray a)` sprays can be very useful. They represent polynomials \nwhose coefficients polynomially depend on some parameters. \nActually there is a type alias of `Spray (Spray a)` in **hspray**, namely \n`SimpleParametricSpray a`, and there are some convenient functions to deal \nwith sprays of this type. There is also a type alias of \n`SimpleParametricSpray Rational`, namely `SimpleParametricQSpray`.\nFor example we can print our `SimpleParametricQSpray` spray `spray` as follows:\n\n```haskell\nputStrLn $ \n  prettySimpleParametricQSprayABCXYZ [\"a\",\"b\"] [\"X\",\"Y\",\"Z\"] spray\n-- { a }*X^2 + { a }*Y^2 + { (2/3)*b }*Z\n```\n\nThe \n[Gegenbauer polynomials](https://en.wikipedia.org/wiki/Gegenbauer_polynomials)\nare a real-life example of polynomials that can be represented by \n`SimpleParametricQSpray` sprays. They are univariate polynomials whose \ncoefficients polynomially depend on a parameter $\\alpha$ (the polynomial \ndependency is clearly visible from the recurrence relation given on \nWikipedia). Here is their recursive implementation in **hspray**:\n\n```haskell\ngegenbauerPolynomial :: Int -\u003e SimpleParametricQSpray \ngegenbauerPolynomial n \n  | n == 0 = unitSpray\n  | n == 1 = (2.^a) *^ x\n  | otherwise = \n    (2.^(n'' ^+^ a) /^ n') *^ (x ^*^ gegenbauerPolynomial (n - 1))\n    ^-^ ((n'' ^+^ 2.^a ^-^ unitSpray) /^ n') *^ gegenbauerPolynomial (n - 2)\n  where \n    x = lone 1 :: SimpleParametricQSpray\n    a = lone 1 :: QSpray\n    n'  = toRational n\n    n'' = constantSpray (n' - 1)\n```\n\nLet's try it:\n\n```haskell\nn = 3\ng = gegenbauerPolynomial n\nputStrLn $ \n  prettySimpleParametricQSprayABCXYZ [\"alpha\"] [\"X\"]  g\n-- { (4/3)*alpha^3 + 4*alpha^2 + (8/3)*alpha }*X^3 + { -2*alpha^2 - 2*alpha }*X\n```\n\nLet's check the differential equation given in the Wikipedia article:\n\n```haskell\ng'  = derivative 1 g\ng'' = derivative 1 g'\nalpha = lone 1 :: QSpray\nx     = lone 1 :: SimpleParametricQSpray\nnAsSpray = constantSpray (toRational n)\nshouldBeZero = \n  (unitSpray ^-^ x^**^2) ^*^ g''\n    ^-^ (2.^alpha ^+^ unitSpray) *^ (x ^*^ g')\n      ^+^ n.^(nAsSpray ^+^ 2.^alpha) *^ g\nputStrLn $ prettySpray shouldBeZero\n-- 0\n```\n\nNow, how to substitute a value to the parameter $\\alpha$? For example, it is \nsaid in the Wikipedia article that this yields the Legendre polynomials for \n$\\alpha = 1/2$. The package provides the function `substituteParameters` to \nperform this task:\n\n```haskell\nimport Data.Ratio (%)\nputStrLn $ \n  prettyQSpray'' $ substituteParameters g [1%2]\n-- (5/2)*X^3 - (3/2)*X\n```\n\nThis is a `Spray Rational` spray.\n\nThe Wikipedia article also provides the value at $1$ of the Gegenbauer \npolynomials in function of $\\alpha$. We can get this value with \n`evalParametricSpray`:\n\n```haskell\nputStrLn $ \n  prettyQSprayXYZ [\"alpha\"] $ evalParametricSpray g [1]\n-- (4/3)*alpha^3 + 2*alpha^2 + (2/3)*alpha\n```\n\nThis is also a `Spray Rational` spray.\n\n\n## Ratios of sprays and general parametric sprays\n\nSince you have just seen that the type `Spray (Spray a)` is named \n`SimpleParametricSpray a`, you probably guessed there is also a more general \ntype named `ParametricSpray a`. Yes, and this is an alias of \n`Spray (RatioOfSprays a)`, where the type `RatioOfSprays a` has not been \ndiscussed yet. The objects of this type represent fractions of multivariate \npolynomials and so this type is a considerable enlargment of the `Spray a` \ntype. Thus the `Spray (RatioOfSprays a)` sprays can represent multivariate \npolynomials whose coefficients depend on some parameters, with a dependence \ndescribed by a fraction of polynomials in these parameters. Let's start with \na short presentation of the ratios of sprays.\n\n### The `RatioOfSprays` type\n\nThe type `RatioOfSprays a`, whose objects represent ratios of sprays, has \nbeen introduced in version 0.2.7.0. \nTo construct a ratio of sprays, apply `%//%` between its numerator and \nits denominator:\n\n```haskell\nimport Math.Algebra.Hspray\nx = qlone 1 -- shortcut for  lone 1 :: Spray Rational\ny = qlone 2 \nrOS = (x ^-^ y) %//% (x^**^2 ^-^ y^**^2)\nputStrLn $ prettyRatioOfQSprays rOS\n-- [ 1 ] %//% [ x + y ]\n```\n\nThe `%//%` operator always returns an *irreducible fraction*. If you are \n***sure*** that your numerator and your denominator are coprime, you can use\nthe `%:%` instead, to gain some efficiency. But if they are not coprime, this \ncan have unfortunate consequences.\n\nThe `RatioOfSprays a` type makes sense when `a` has a field instance, and then \nit has a field instance too. To use the field operations, import the necessary\nmodules from **numeric-prelude**, and hide these operations from the `Prelude`\nmodule; then you can also use the **numeric-prelude** operations for sprays, \ninstead of using `^+^`, `^-^`, `^*^`, `^**^`:\n\n```haskell\nimport Prelude hiding ((+), (-), (*), (/), (^), (*\u003e), (\u003c*))\nimport qualified Prelude as P\nimport Algebra.Additive              \nimport Algebra.Module\nimport Algebra.RightModule\nimport Algebra.Ring\nimport Algebra.Field              \nimport Math.Algebra.Hspray\nx = qlone 1  \ny = qlone 2 \np = x^2 - 3*^(x * y) + y^3 \nq = x - y\nrOS1 = p^2 %//% q\nrOS2 = rOS1 + unitRatioOfSprays\nrOS = rOS1^2 + rOS1*rOS2 - rOS1/rOS2 + rOS2 -- slow!\n(rOS1 + rOS2) * (rOS1 - rOS2) == rOS1^2 - rOS2^2\n-- True\nrOS / rOS == unitRatioOfSprays\n-- True\n```\n\nActually, as of version 0.5.0.0, it is possible to apply the operations \n`^+^`, `^-^`, `^*^`, `^**^` and `*^` to the ratios of sprays.\n\nThe `RatioOfSprays a` type also has left and right module instances over `a` \nand over `Spray a` as well. That means you can multiply a ratio of sprays by\na scalar and by a spray, by using, depending on the side, either `*\u003e` or `\u003c*`:\n\n```haskell\nimport Data.Ratio ( (%) )\nrOS' = (3%4::Rational) *\u003e rOS^2  +  p *\u003e rOS\n```\n\nYou can also divide a ratio of sprays by a spray with `%/%`:\n\n```haskell\np *\u003e (rOS' %/% p) == rOS'\n-- True\nrOS1 %/% p == p %//% q\n-- True\n```\n\nWhen `a` has a field instance, both a `Spray a` spray and a `RatioOfSprays a` \nratio of sprays can be divided by a scalar with the `/\u003e` operator:\n\n```haskell\nk = 3 :: Rational\n(p /\u003e k) *\u003e rOS == p *\u003e (rOS /\u003e k)\n-- True\n```\n\nUse `evalRatioOfSprays` to evaluate a ratio of sprays:\n\n```haskell\nimport Data.Ratio ( (%) )\nf :: Algebra.Field.C a =\u003e a -\u003e a -\u003e a\nf u v = u^2 + u*v - u/v + v\nrOS == f rOS1 rOS2\n-- True\nvalues = [2%3, 7%4]\nr1 = evalRatioOfSprays rOS1 values\nr2 = evalRatioOfSprays rOS2 values\nevalRatioOfSprays rOS values == f r1 r2\n-- True\n```\n\n### The `ParametricSpray` type\n\nRecall that `SimpleParametricSpray a = Spray (Spray a)` and \n`ParametricSpray a = Spray (RatioOfSprays a)`, and we have the aliases \n`SimpleParametricQSpray = SimpleParametricSpray Rational` and \n`ParametricQSpray = ParametricSpray Rational`.\n\nThe functions `substituteParameters` and `evalParametricSpray`, that we \npreviously applied to a `SimpleParametricSpray a` spray, are also applicable \nto a `ParametricSpray a` spray. We didn't mention the function \n`changeParameters` yet, which is also applicable to these two types of \nparametric sprays. This function performs some polynomial transformations of \nthe parameters of a parametric spray. For example, consider the \n[Jacobi polynomials](https://en.wikipedia.org/wiki/Jacobi_polynomials). \nThey are univariate polynomials with two parameters $\\alpha$ and $\\beta$. \nThey are implemented in **hspray** as `ParametricQSpray` sprays. In fact \nit seems that the coefficients of the Jacobi polynomials *polynomially* \ndepend on $\\alpha$ and $\\beta$, and if this is true one could implement them \nas `SimpleParametricQSpray` sprays. I will come back to this point later. The \nrecurrence relation defining the Jacobi polynomials involves a division which \nmakes the type `ParametricQSpray` necessary anyway. \n\nThe `changeParameters` function is useful to derive the Gegenbauer polynomials \nfrom the Jacobi polynomials. Indeed, as asserted in the Wikipedia article, \nthe Gegenbauer polynomials coincide, up to a factor, with the Jacobi \npolynomials with parameters $\\alpha - 1/2$ and $\\alpha - 1/2$. Here is how \nto apply the `changeParameters` function to get this special case of Jacobi \npolynomials:\n\n```haskell\nimport Data.Ratio ( (%) )\nj = jacobiPolynomial 3\nalpha = qlone 1\nalpha' = alpha ^-^ constantSpray (1%2)\nj' = changeParameters j [alpha', alpha']\n```\n\nNow let's come back to the conjecture claiming that the coefficients of the \nJacobi polynomials *polynomially* depend on $\\alpha$ and $\\beta$, and thus \nthese polynomials can be represented by `SimpleParametricQSpray` sprays. \nMaybe this can be deduced from a formula given in the Wikipedia article, I \ndidn't spend some time on this problem. I made this conjecture because I \nobserved this fact for some small values of $n$, and I tried the function\n`canCoerceToSimpleParametricSpray` for other values, which always returned \n`True`. One can apply the function `asSimpleParametricSpray` to perform the \ncoercion.\n\n\n## The `OneParameterSpray` type\n\nThere is a third type of parametric sprays in the package, namely the \n`OneParameterSpray` sprays. The objects of this type represent \nmultivariate polynomials whose coefficients are fractions \nof polynomials *in only one variable* (the parameter). So they are less \ngeneral than the `ParametricSpray` sprays.\n\nThese sprays are no longer very useful. They have been introduced in version \n0.2.5.0 and this is the first type of parametric sprays that has been provided \nby the package. When the more general `ParametricSpray` sprays have been \nintroduced, I continued to develop the `OneParameterSpray` sprays because they\nwere more efficient than the univariate `ParametricSpray` sprays. But as of \nversion 0.4.0.0, this is no longer the case. This is what I concluded from \nsome benchmarks on the *Jack polynomials*, implemented in the\n[**jackpolynomials** package](https://github.com/stla/jackpolynomials). \n\nThese are sprays of type `Spray (RatioOfPolynomials a)`, where the type \n`RatioOfPolynomials a` deals with objects that represent fractions of \n*univariate* polynomials. The type of these univariate polynomials is \n`Polynomial a`. \n\nThe functions we have seen for the simple parametric sprays and the parametric \nsprays, `substituteParameters`, `evalParametricSpray`, and `changeParameters`, \nare also applicable to the one-parameter sprays. \n\nThe `OneParameterSpray` sprays were used in the \n[**jackpolynomials** package](https://github.com/stla/jackpolynomials) to \nrepresent the Jack polynomials with a symbolic Jack parameter but they have \nbeen replaced with the `ParametricSpray` sprays.\n\n\n## Other features\n\nOther features offered by the package include: resultant and subresultants of \ntwo polynomials, Sturm-Habicht sequence of a polynomial, number of real roots \nof a univariate polynomial, and greatest common divisor of two polynomials with \ncoefficients in a field.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstla%2Fhspray","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fstla%2Fhspray","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstla%2Fhspray/lists"}