https://github.com/stla/ratioofqsprays
Fractions of multivariate polynomials with rational coefficients.
https://github.com/stla/ratioofqsprays
multivariate-polynomials polynomials r rational-functions
Last synced: about 1 year ago
JSON representation
Fractions of multivariate polynomials with rational coefficients.
- Host: GitHub
- URL: https://github.com/stla/ratioofqsprays
- Owner: stla
- Created: 2024-04-04T01:52:33.000Z (about 2 years ago)
- Default Branch: main
- Last Pushed: 2024-08-04T04:26:48.000Z (almost 2 years ago)
- Last Synced: 2024-08-18T09:55:53.381Z (almost 2 years ago)
- Topics: multivariate-polynomials, polynomials, r, rational-functions
- Language: R
- Homepage:
- Size: 224 KB
- Stars: 0
- Watchers: 2
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.Rmd
- Changelog: NEWS.md
Awesome Lists containing this project
README
---
title: "The 'ratioOfQsprays' package"
author: "Stéphane Laurent"
date: "`r Sys.Date()`"
output: github_document
---
***Fractions of multivariate polynomials with rational coefficients.***
[](https://github.com/stla/ratioOfQsprays/actions/workflows/R-CMD-check.yaml)
___
The [**qspray** package](https://github.com/stla/qspray) allows arithmetic
(and more) on multivariate polynomials with rational coefficients. Based on
this one, the **ratioOfQsprays** package allows to manipulate *fractions* of
multivariate polynomials with rational coefficients.
These notes about the **ratioOfQsprays** package assume that the reader is a
bit familiar with the **qspray** package.
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE, collapse = TRUE, message = FALSE)
```
## Creating a `ratioOfQsprays`
A `ratioOfQsprays` object represents a fraction of two multivariate
polynomials with rational coefficients. Such polynomials are represented by
`qspray` objects. The easiest way to create a `ratioOfQsprays` is to introduce
the variables of the polynomials with the `qlone` function (from the **qspray**
package), and then to build a `qspray` numerator and a `qspray` denominator
with the arithmetic operations. For example:
```{r}
library(ratioOfQsprays)
f <- function(x1, x2, x3) {
(2*x1^2 + x2*x3) / (4*x1 - 3*x3 + 1)
}
# variables:
x1 <- qlone(1)
x2 <- qlone(2)
x3 <- qlone(3)
# the 'ratioOfQsprays':
( roq <- f(x1, x2, x3) )
```
The denominator of a `ratioOfQsprays` fraction of polynomials is always *monic*.
That means it is a polynomial whose leading coefficient is 1.
Arithmetic on `ratioOfQsprays` objects is available:
```{r}
roq^2
roq - roq
1 / roq
2*roq + (x2 + x3)/x1
```
You don't like my quotient bar `%//%`? Be patient, we will see how to change
it later. I adopted this large quotient bar because it is more easy to find
it than a single slash `/` in a `ratioOfQsprays` having a long expression.
Rational numbers and `qspray` polynomials are coercible to
`ratioOfQsprays` objects, and then you can also perform arithmetic operations
between a `ratioOfQsprays` and such an object:
```{r}
2 * roq
"1/2" * roq
roq + gmp::as.bigq("7/3")
x1 + roq + x3^2
```
The result of an arithmetic operation is always an irreducible fraction.
To perform this step, the C++ library **CGAL** is used to compute a greatest
common divisor of the numerator and the denominator of the possibly non-reduced
fraction resulting from the arithmetic operation, and then to divide both of
them by this greatest common divisor. This is very efficient in general.
## Evaluating a `ratioOfQsprays`
Use `evalRatioOfQsprays` to evaluate a `ratioOfQsprays`. This function returns
a `bigq` number:
```{r}
library(gmp) # rational numbers
x <- c("4", "3", "2/5")
evalRatioOfQsprays(roq, x)
x <- as.bigq(x)
evalRatioOfQsprays(roq, x)
f(x[1], x[2], x[3])
```
It is also possible to substitute some values to only a subset of the
variables, with the help of the function `substituteRatioOfQsprays`. You have
to indicate the variables you don't want to replace with `NA`:
```{r}
x <- c(NA, "3", "2/5")
substituteRatioOfQsprays(roq, x)
x <- as.bigq(x)
f(x1, x[2], x[3])
```
And it is possible to convert a `ratioOfQsprays` to a function which is
evaluated by **Ryacas**:
```{r}
fyac <- as.function(roq)
fyac("4", "3", "2/5") # = evalRatioOfQsprays(roq, c("4", "3", "2/5"))
```
Actually you can pass some literal variables to this function:
```{r}
fyac("x", "3", "2/5") # = substituteRatioOfQsprays(roq, c(NA, "3", "2/5"))
fyac("x", "y", "z") # = roq
fyac("x", "x", "x")
```
Complex numbers are allowed; the imaginary unit is denoted by `I`. See the
[**Yacas** documentation](https://yacas.readthedocs.io/en/latest/) for more
information.
```{r}
fyac("Sqrt(2)", "2 + 2*I", "3")
```
You can get numerical approximations by setting the option `N=TRUE` in
`as.function`:
```{r}
fyacN <- as.function(roq, N = TRUE)
fyacN("4", "3", "2/5")
fyacN("x", "3", "2/5")
fyacN("Sqrt(2)", "2 + 2*I", "3")
```
Let us also mention the `substituteSomeRatioOfQsprays` function. This function
allows to substitute the variables of a `ratioOfQsprays` fraction of polynomials
with some `ratioOfQsprays` objects.
## Querying a `ratioOfQsprays`
A couple of functions to query a `ratioOfQsprays` are available:
```{r}
getNumerator(roq)
getDenominator(roq)
numberOfVariables(roq)
isConstant(roq)
isConstant(roq / roq)
isUnivariate(roq)
isUnivariate(x1 / (x1^2 + 1))
isPolynomial(roq)
isPolynomial((x1^2 - x2^2) / (x1 - x2))
```
## Showing a `ratioOfQsprays`
As you have seen, the variables of `roq` are denoted by `x`, `y`, `z`. This is
the default way of printing a `ratioOfQsprays` which has no more than three
variables. If it has more than three variables, then they are denoted by
`x1`, `x2`, `x3`, ...:
```{r}
x4 <- qlone(4)
roq / x4
```
It is possible to control the way a `ratioOfQsprays` is printed. For example,
let's say you want to print `roq` by using `a1`, `a2`, `a3` for the variables
and you want to change the symbol for the quotient bar:
```{r}
showRatioOfQspraysOption(roq, "x") <- "a"
showRatioOfQspraysOption(roq, "quotientBar") <- " / "
roq
```
Now, if you perform an arithmetic operation between `roq` *at first position*
and an another `ratioOfQsprays`, these show options are passed to the result if
possible:
```{r}
roq + (x1 + 1)/x2
```
If you perform an arithmetic operation between `roq` and an object coercible to
a `ratioOfQsprays` object but which is not a `ratioOfQsprays` object, such as a
`bigq` number or a `qspray` object, the show options of `roq` are passed to
the result, even if `roq` is not at the first position:
```{r}
x1 * roq
```
An obvious example of a situation in which it is not always possible to
transfer the show options is when you use three letters for the variables, e.g.
```{r}
showRatioOfQspraysOption(roq, "showQspray") <- showQsprayXYZ(c("A", "B", "C"))
roq
```
but then you add to `roq` a `ratioOfQsprays` containing the fourth variable:
```{r}
roq + x4/(x4 + 1)
```
Obviously it is not possible to denote the resulting fraction of polynomials
with the letters `A`, `B` and `C`. The solution I adopted consists in
taking the first of these letters and to index it. The same method is used
for the `qspray` polynomials.
## Transforming a `ratioOfQsprays`
Let's take a `ratioOfQsprays` fraction of polynomials:
```{r}
f <- function(x, y, z) {
(2*x^2 + y*z) / (4*x - 3*z + 1)
}
x <- qlone(1); y <- qlone(2); z <- qlone(3)
roq <- f(x, y, z)
```
You can differentiate it:
```{r}
derivRatioOfQsprays(roq, 2) # derivative w.r.t. y
```
You can permute its variables:
```{r}
swapVariables(roq, 2, 3) == f(x, z, y)
```
You can perform some polynomial changes of its variables:
```{r}
changeVariables(roq, list(x+1, y^2, x+y+z)) == f(x+1, y^2, x+y+z)
```