Catalogue of GP/PARI Functions: Standard monadic or dyadic operators
Author: Karim Belabas
Keywords: PARI, GP, DOC

## Standard monadic or dyadic operators

#### +/-

The expressions `+`x and `-`x refer to monadic operators (the first does nothing, the second negates x).

The library syntax is `GEN gneg(GEN x)` for `-`x.

#### +

The expression x `+` y is the sum of x and y. Addition between a scalar type x and a `t_COL` or `t_MAT` y returns respectively [y[1] + x, y[2],...] and y + x Id. Other additions between a scalar type and a vector or a matrix, or between vector/matrices of incompatible sizes are forbidden.

The library syntax is `GEN gadd(GEN x, GEN y)`.

#### -

The expression x `-` y is the difference of x and y. Subtraction between a scalar type x and a `t_COL` or `t_MAT` y returns respectively [y[1] - x, y[2],...] and y - x Id. Other subtractions between a scalar type and a vector or a matrix, or between vector/matrices of incompatible sizes are forbidden.

The library syntax is `GEN gsub(GEN x, GEN y)` for x `-` y.

#### *

The expression x `*` y is the product of x and y. Among the prominent impossibilities are multiplication between vector/matrices of incompatible sizes, between a `t_INTMOD` or `t_PADIC` Restricted to scalars, `*` is commutative; because of vector and matrix operations, it is not commutative in general.

Multiplication between two `t_VEC`s or two `t_COL`s is not allowed; to take the scalar product of two vectors of the same length, transpose one of the vectors (using the operator `~` or the function `mattranspose`, see Section se:linear_algebra) and multiply a line vector by a column vector:

      ? a = [1,2,3];
      ? a * a
        ***   at top-level: a*a
        ***                  ^--
        *** _*_: forbidden multiplication t_VEC * t_VEC.
      ? a * a~
      %2 = 14

If x,y are binary quadratic forms, compose them; see also `qfbnucomp` and `qfbnupow`. If x,y are `t_VECSMALL` of the same length, understand them as permutations and compose them.

The library syntax is `GEN gmul(GEN x, GEN y)` for x `*` y. Also available is `GEN gsqr(GEN x)` for x `*` x.

#### /

The expression x `/` y is the quotient of x and y. In addition to the impossibilities for multiplication, note that if the divisor is a matrix, it must be an invertible square matrix, and in that case the result is x*y-1. Furthermore note that the result is as exact as possible: in particular, division of two integers always gives a rational number (which may be an integer if the quotient is exact) and not the Euclidean quotient (see x `\` y for that), and similarly the quotient of two polynomials is a rational function in general. To obtain the approximate real value of the quotient of two integers, add `0.` to the result; to obtain the approximate p-adic value of the quotient of two integers, add `O(p^k)` to the result; finally, to obtain the Taylor series expansion of the quotient of two polynomials, add `O(X^k)` to the result or use the `taylor` function (see Section se:taylor).

The library syntax is `GEN gdiv(GEN x, GEN y)` for x `/` y.

#### \

The expression `x \y` is the Euclidean quotient of x and y. If y is a real scalar, this is defined as `floor(x/y)` if y > 0, and `ceil(x/y)` if y < 0 and the division is not exact. Hence the remainder `x - (x\y)*y` is in [0, |y|[.

Note that when y is an integer and x a polynomial, y is first promoted to a polynomial of degree 0. When x is a vector or matrix, the operator is applied componentwise.

The library syntax is `GEN gdivent(GEN x, GEN y)` for x `\` y.

#### \/

The expression x `\/` y evaluates to the rounded Euclidean quotient of x and y. This is the same as `x \y` except for scalar division: the quotient is such that the corresponding remainder is smallest in absolute value and in case of a tie the quotient closest to + oo is chosen (hence the remainder would belong to ]{-}|y|/2, |y|/2]).

When x is a vector or matrix, the operator is applied componentwise.

The library syntax is `GEN gdivround(GEN x, GEN y)` for x `\/` y.

#### %

The expression `x % y` evaluates to the modular Euclidean remainder of x and y, which we now define. When x or y is a non-integral real number, `x%y` is defined as `x - (x\y)*y`. Otherwise, if y is an integer, this is the smallest non-negative integer congruent to x modulo y. (This actually coincides with the previous definition if and only if x is an integer.) If y is a polynomial, this is the polynomial of smallest degree congruent to x modulo y. For instance:

      ? (1/2) % 3
      %1 = 2
      ? 0.5 % 3
      %2 = 0.5000000000000000000000000000
      ? (1/2) % 3.0
      %3 = 1/2

Note that when y is an integer and x a polynomial, y is first promoted to a polynomial of degree 0. When x is a vector or matrix, the operator is applied componentwise.

The library syntax is `GEN gmod(GEN x, GEN y)` for x `%` y.

#### ^

The expression x^n is powering.

* If the exponent n is an integer, then exact operations are performed using binary (left-shift) powering techniques. If x is a p-adic number, its precision will increase if vp(n) > 0. Powering a binary quadratic form (types `t_QFI` and `t_QFR`) returns a representative of the class, which is always reduced if the input was. (In particular, `x^1` returns x itself, whether it is reduced or not.)

PARI is able to rewrite the multiplication x * x of two identical objects as x^2, or `sqr`(x). Here, identical means the operands are two different labels referencing the same chunk of memory; no equality test is performed. This is no longer true when more than two arguments are involved.

* If the exponent n is not an integer, powering is treated as the transcendental function exp(nlog x), and in particular acts componentwise on vector or matrices, even square matrices ! (See Section se:trans.)

* As an exception, if the exponent is a rational number p/q and x an integer modulo a prime or a p-adic number, return a solution y of y^q = x^p if it exists. Currently, q must not have large prime factors. Beware that

      ? Mod(7,19)^(1/2)
      %1 = Mod(11, 19) /* is any square root */
      ? sqrt(Mod(7,19))
      %2 = Mod(8, 19)  /* is the smallest square root */
      ? Mod(7,19)^(3/5)
      %3 = Mod(1, 19)
      ? %3^(5/3)
      %4 = Mod(1, 19)  /* Mod(7,19) is just another cubic root */

* If the exponent is a negative integer, an inverse must be computed. For non-invertible `t_INTMOD` x, this will fail and implicitly exhibit a non trivial factor of the modulus:

      ? Mod(4,6)^(-1)
        ***   at top-level: Mod(4,6)^(-1)
        ***                         ^ — --
        *** _^_: impossible inverse modulo: Mod(2, 6).

(Here, a factor 2 is obtained directly. In general, take the gcd of the representative and the modulus.) This is most useful when performing complicated operations modulo an integer N whose factorization is unknown. Either the computation succeeds and all is well, or a factor d is discovered and the computation may be restarted modulo d or N/d.

For non-invertible `t_POLMOD` x, the behavior is the same:

      ? Mod(x^2, x^3-x)^(-1)
        ***   at top-level: Mod(x^2,x^3-x)^(-1)
        ***                               ^ — --
        *** _^_: impossible inverse in RgXQ_inv: Mod(x^2, x^3 - x).

Note that the underlying algorihm (subresultant) assumes the base ring is a domain:

      ? a = Mod(3*y^3+1, 4); b = y^6+y^5+y^4+y^3+y^2+y+1; c = Mod(a,b);
      ? c^(-1)
        ***   at top-level: Mod(a,b)^(-1)
        ***                         ^ — --
        *** _^_: impossible inverse modulo: Mod(2, 4).

In fact c is invertible, but ℤ/4ℤ is not a domain and the algorithm fails. It is possible for the algorithm to succeed in such situations and any returned result will be correct, but chances are an error will occur first. In this specific case, one should work with 2-adics. In general, one can also try the following approach

      ? inversemod(a, b) =
      { my(m, v = variable(b));
        m = polsylvestermatrix(polrecip(a), polrecip(b));
        m = matinverseimage(m, matid(#m)[,1]);
        Polrev(m[1..poldegree(b)], v);
      }
      ? inversemod(a,b)
      %2 = Mod(2,4)*y^5 + Mod(3,4)*y^3 + Mod(1,4)*y^2 + Mod(3,4)*y + Mod(2,4)

This is not guaranteed to work either since `matinverseimage` must also invert pivots. See Section se:linear_algebra.

For a `t_MAT` x, the matrix is expected to be square and invertible, except in the special case `x^(-1)` which returns a left inverse if one exists (rectangular x with full column rank).

      ? x = Mat([1;2])
      %1 =
      [1]

      [2]

      ? x^(-1)
      %2 =
      [1 0]

The library syntax is `GEN gpow(GEN x, GEN n, long prec)` for x^n.

#### cmp(x, y)

Gives the result of a comparison between arbitrary objects x and y (as -1, 0 or 1). The underlying order relation is transitive, the function returns 0 if and only if x `===` y. It has no mathematical meaning but satisfies the following properties when comparing entries of the same type:

* two `t_INT`s compare as usual (i.e. `cmp`(x,y) < 0 if and only if x < y);

* two `t_VECSMALL`s of the same length compare lexicographically;

* two `t_STR`s compare lexicographically.

In case all components are equal up to the smallest length of the operands, the more complex is considered to be larger. More precisely, the longest is the largest; when lengths are equal, we have matrix > vector > scalar. For example:

      ? cmp(1, 2)
      %1 = -1
      ? cmp(2, 1)
      %2 = 1
      ? cmp(1, 1.0)   \\ note that 1 == 1.0, but (1===1.0) is false.
      %3 = -1
      ? cmp(x + Pi, [])
      %4 = -1

This function is mostly useful to handle sorted lists or vectors of arbitrary objects. For instance, if v is a vector, the construction `vecsort(v, cmp)` is equivalent to `Set(v)`.

The library syntax is `GEN cmp_universal(GEN x, GEN y)`.

#### divrem(x, y, {v})

Creates a column vector with two components, the first being the Euclidean quotient (`x \y`), the second the Euclidean remainder (`x - (x\y)*y`), of the division of x by y. This avoids the need to do two divisions if one needs both the quotient and the remainder. If v is present, and x, y are multivariate polynomials, divide with respect to the variable v.

Beware that `divrem(x,y)[2]` is in general not the same as `x % y`; no GP operator corresponds to it:

      ? divrem(1/2, 3)[2]
      %1 = 1/2
      ? (1/2) % 3
      %2 = 2
      ? divrem(Mod(2,9), 3)[2]
       ***   at top-level: divrem(Mod(2,9),3)[2
       ***                 ^ —  —  —  —  —  — --
       ***   forbidden division t_INTMOD \ t_INT.
      ? Mod(2,9) % 6
      %3 = Mod(2,3)

The library syntax is `GEN divrem(GEN x, GEN y, long v = -1)` where `v` is a variable number. Also available is `GEN gdiventres(GEN x, GEN y)` when v is not needed.

#### lex(x, y)

Gives the result of a lexicographic comparison between x and y (as -1, 0 or 1). This is to be interpreted in quite a wide sense: It is admissible to compare objects of different types (scalars, vectors, matrices), provided the scalars can be compared, as well as vectors/matrices of different lengths. The comparison is recursive.

In case all components are equal up to the smallest length of the operands, the more complex is considered to be larger. More precisely, the longest is the largest; when lengths are equal, we have matrix > vector > scalar. For example:

      ? lex([1,3], [1,2,5])
      %1 = 1
      ? lex([1,3], [1,3,-1])
      %2 = -1
      ? lex([1], [[1]])
      %3 = -1
      ? lex([1], [1]~)
      %4 = 0

The library syntax is `GEN lexcmp(GEN x, GEN y)`.

#### max(x, y)

Creates the maximum of x and y when they can be compared.

The library syntax is `GEN gmax(GEN x, GEN y)`.

#### max(x, y)

Creates the maximum of x and y when they can be compared.

The library syntax is `GEN gmax(GEN x, GEN y)`.

#### powers(x, n, {x0})

For non-negative n, return the vector with n+1 components [1,x,...,x^n] if `x0` is omitted, and [x0, x0*x, ..., x0*x^n] otherwise.

      ? powers(Mod(3,17), 4)
      %1 = [Mod(1, 17), Mod(3, 17), Mod(9, 17), Mod(10, 17), Mod(13, 17)]
      ? powers(Mat([1,2;3,4]), 3)
      %2 = [[1, 0; 0, 1], [1, 2; 3, 4], [7, 10; 15, 22], [37, 54; 81, 118]]
      ? powers(3, 5, 2)
      %3 = [2, 6, 18, 54, 162, 486]

When n < 0, the function returns the empty vector `[]`.

The library syntax is `GEN gpowers0(GEN x, long n, GEN x0 = NULL)`. Also available is `GEN gpowers(GEN x, long n)` when `x0` is `NULL`.

#### shift(x, n)

Shifts x componentwise left by n bits if n ≥ 0 and right by |n| bits if n < 0. May be abbreviated as x `<<` n or x `>>` (-n). A left shift by n corresponds to multiplication by 2^n. A right shift of an integer x by |n| corresponds to a Euclidean division of x by 2|n| with a remainder of the same sign as x, hence is not the same (in general) as x `\` 2^n.

The library syntax is `GEN gshift(GEN x, long n)`.

#### shiftmul(x, n)

Multiplies x by 2^n. The difference with `shift` is that when n < 0, ordinary division takes place, hence for example if x is an integer the result may be a fraction, while for shifts Euclidean division takes place when n < 0 hence if x is an integer the result is still an integer.

The library syntax is `GEN gmul2n(GEN x, long n)`.

#### sign(x)

sign (0, 1 or -1) of x, which must be of type integer, real or fraction; `t_QUAD` with positive discriminants and `t_INFINITY` are also supported.

The library syntax is `GEN gsigne(GEN x)`.

#### vecmax(x, {&v})

If x is a vector or a matrix, returns the largest entry of x, otherwise returns a copy of x. Error if x is empty.

If v is given, set it to the index of a largest entry (indirect maximum), when x is a vector. If x is a matrix, set v to coordinates [i,j] such that x[i,j] is a largest entry. This flag is ignored if x is not a vector or matrix.

      ? vecmax([10, 20, -30, 40])
      %1 = 40
      ? vecmax([10, 20, -30, 40], &v); v
      %2 = 4
      ? vecmax([10, 20; -30, 40], &v); v
      %3 = [2, 2]

The library syntax is `GEN vecmax0(GEN x, GEN *v = NULL)`. When v is not needed, the function `GEN vecmax(GEN x)` is also available.

#### vecmin(x, {&v})

If x is a vector or a matrix, returns the smallest entry of x, otherwise returns a copy of x. Error if x is empty.

If v is given, set it to the index of a smallest entry (indirect minimum), when x is a vector. If x is a matrix, set v to coordinates [i,j] such that x[i,j] is a smallest entry. This is ignored if x is not a vector or matrix.

      ? vecmin([10, 20, -30, 40])
      %1 = -30
      ? vecmin([10, 20, -30, 40], &v); v
      %2 = 3
      ? vecmin([10, 20; -30, 40], &v); v
      %3 = [2, 1]

The library syntax is `GEN vecmin0(GEN x, GEN *v = NULL)`. When v is not needed, the function `GEN vecmin(GEN x)` is also available.

#### Comparison and Boolean operators

The six standard comparison operators `<=` , `<` , `>=` , `>` , `==` , `!=` are available in GP. The result is 1 if the comparison is true, 0 if it is false. The operator `==` is quite liberal : for instance, the integer 0, a 0 polynomial, and a vector with 0 entries are all tested equal.

The extra operator `===` tests whether two objects are identical and is much stricter than `==` : objects of different type or length are never identical.

For the purpose of comparison, `t_STR` objects are compared using the standard lexicographic order, and comparing them to objects of a different type raises an exception.

GP accepts `<>` as a synonym for `!=` . On the other hand, `=` is definitely not a synonym for `==` : it is the assignment statement.

The standard boolean operators `||` (inclusive or), `&&` (and) and `!` (not) are also available.