Any nonzero value is interpreted as *true* and any zero as *false*
(this includes empty vectors or matrices). The standard boolean operators
`||`

(inclusive or), `&&`

(and) and `!`

in prefix notation (not) are available.
Their value is 1 (true) or 0 (false):

? a && b \\ 1 iff a and b are nonzero ? a || b \\ 1 iff a or b is nonzero ? !a \\ 1 iff a is zero

The standard real comparison operators ` <= `

, ` < `

, ` >= `

,
` > `

, are available in GP. The result is 1 if the comparison is true, 0
if it is false. These operators allow to compare integers (`t_INT`

),
rational (`t_FRAC`

) or real (`t_REAL`

) numbers,
real quadratic numbers (`t_QUAD`

of positive discriminant) and infinity
(`oo`

, `t_INFINITY`

).

By extension, two character strings (`t_STR`

) are compared using
the standard lexicographic order. Comparing a string to an object of a
different type raises an exception. See also the `cmp`

universal
comparison function.

Two operators allow to test for equality: ` == `

(equality up to type
coercion) and ` === `

(identity). The result is 1 if equality is decided,
else 0.

The operator ` === `

is strict: objects of different type or length are
never identical, polynomials in different variables are never identical,
even if constant. On the contrary, ` == `

is very liberal: a ` == `

b
decides whether there is a natural map sending a to the domain of b
or sending b to the domain of a, such that the comparison makes sense
and equality holds. For instance

? 4 == Mod(1,3) \\ equal %1 = 1 ? 4 === Mod(1,3) \\ but not identical %2 = 0 ? 'x == 'y \\ not equal (nonconstant and different variables) %3 = 0 ? Pol(0,'x) == Pol(0,'y) \\ equal (constant: ignore variable) %4 = 1 ? Pol(0,'x) == Pol(0,'y) \\ not identical %5 = 0 ? 0 == Pol(0) \\ equal %6 = 1 ? [0] == 0 \\ equal %7 = 1 ? [0, 0] == 0 \\ equal %8 = 1 ? [0] == [0,0] \\ not equal %9 = 1

In particular ` == `

is not transitive in general; it is
transitive when used to compare objects known to have the same type. The
operator ` === `

is transitive. The ` == `

operator allows two
equivalent negated forms: ` != `

or ` <> `

; there is no negated form for
` === `

.

Do not mistake ` = `

for ` == `

: it is the assignment statement.

The expressions `+`

x and `-`

x refer
to monadic operators: the first does nothing, the second negates x.

The library syntax is `GEN `

for **gneg**(GEN x)`-`

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 `

for x **gsub**(GEN x, GEN y)`-`

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 `

for x **gmul**(GEN x, GEN y)`*`

y.
Also available is `GEN `

for x **gsqr**(GEN 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 `

for x **gdiv**(GEN x, GEN y)`/`

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 `

for x **gdivent**(GEN x, GEN y)`\`

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 `

for x **gdivround**(GEN x, GEN y)`\/`

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 nonintegral real number, `x%y`

is defined as
`x - (x\y)*y`

. Otherwise, if y is an integer, this is
the smallest
nonnegative 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 `

for x **gmod**(GEN x, GEN y)`%`

y.

When `op`

is a binary arithmetic operator among
`+`

, `-`

, `%`

, `/`

, `\`

or `\/`

, the construct
x *op* = y is a shortcut for x = x *op* y.

? v[1] += 10 \\ increment v[1] by 10 ? a /= 2 \\ divide a by 2

`x++`

is a shortcut for `x = x + 1`

.

`x--`

is a shortcut for `x = x - 1`

.

The expression x^n is powering.

***** If the exponent n is an integer, then exact operations are performed
using binary (left-shift) powering techniques. By definition, x^0 is
(an empty product interpreted as) an exact 1 in the underlying prime
ring:

? 0.0 ^ 0 %1 = 1 ? (1 + O(2^3)) ^ 0 %2 = 1 ? (1 + O(x)) ^ 0 %3 = 1 ? Mod(2,4)^0 %4 = Mod(1,4) ? Mod(x,x^2)^0 %5 = Mod(1, x^2)

If x is a p-adic number, its precision will increase if v_{p}(n) > 0 and
n != 0. Powering a binary quadratic form (type `t_QFB`

) returns a
representative of the class, which is reduced if the input was.
(In particular, `x^1`

returns x itself, whether it is reduced or
not.)

PARI rewrites the multiplication x * x of two *identical*
objects as x^2. Here, identical means the operands are reference the same
chunk of memory; no equality test is performed. This is no longer true when
more than two arguments are involved.

? a = 1 + O(2); b = a; ? a * a \\ = a^2, precision increases %2 = 1 + O(2^3) ? a * b \\ not rewritten as a^2 %3 = 1 + O(2) ? a*a*a \\ not rewritten as a^3 %4 = 1 + O(2)

***** If the exponent is a rational number p/q the behaviour depends
on x. If x is a complex number, return exp(n log x) (principal
branch), in an exact form if possible:

? 4^(1/2) \\ 4 being a square, this is exact %1 = 2 ? 2^(1/2) \\ now inexact %2 = 1.4142135623730950488016887242096980786 ? (-1/4)^(1/2) \\ exact again %3 = 1/2*I ? (-1)^(1/3) %4 = 0.500...+ 0.866...*I

Note that even though -1 is an exact cube root of -1, it is not exp(log(-1)/3); the latter is returned.

Otherwise return a solution y of y^q = x^p if it exists; beware that this is defined up to q-th roots of 1 in the base field. Intmods modulo composite numbers are not supported.

? 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(1,4)^(1/2) *** at top-level: Mod(1,4)^(1/2) *** ^ — — *** _^_: not a prime number in gpow: 4.

***** If the exponent is a negative integer or rational number,
an inverse must be computed. For noninvertible `t_INTMOD`

x, this
will fail and (for n an integer) implicitly exhibit a 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 noninvertible `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 that 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 that 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]

***** Finally, if the exponent n is not an rational number, powering is
treated as the transcendental function exp(nlog x), although it will be
more precise than the latter when n and x are exact:

? s = 1/2 + 10^14 * I ? localprec(200); z = 2^s \\ for reference ? exponent(2^s - z) %3 = -127 \\ perfect ? exponent(exp(s * log(2)) - z) %4 = -84 \\ not so good

The second computation is less precise because log(2) is first computed to 38 decimal digits, then multiplied by s, which has a huge imaginary part amplifying the error.

In this case, x `: — >`

x^n is treated as a transcendental function and
and in particular acts
componentwise on vector or matrices, even square matrices ! (See
Section se:trans.) If x is 0 and n is an inexact 0, this will raise
an exception:

? 4 ^ 1.0 %1 = 4.0000000000000000000000000000000000000 ? 0^ 0.0 *** at top-level: 0^0.0 *** ^ — - *** _^_: domain error in gpow(0,n): n <= 0

The library syntax is `GEN `

for x^n.**gpow**(GEN x, GEN n, long prec)

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)

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 `

where **divrem**(GEN x, GEN y, long v = -1)`v`

is a variable number.
Also available is `GEN `

when v is
not needed.**gdiventres**(GEN x, GEN 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; finally, when comparing two scalars, a complex number a + I*b is interpreted as a vector [a,b] and a real number a as [a,0]. 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 ? lex(2 - I, 1) %5 = 1 ? lex(2 - I, 2) %6 = 2

The library syntax is `GEN `

.**lexcmp**(GEN x, GEN y)

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

The library syntax is `GEN `

.**gmax**(GEN x, GEN y)

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

The library syntax is `GEN `

.**gmin**(GEN x, GEN y)

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)

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 (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)

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 `

.
When v is not needed, the function **vecmax0**(GEN x, GEN *v = NULL)`GEN `

is
also available.**vecmax**(GEN x)

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 `

.
When v is not needed, the function **vecmin0**(GEN x, GEN *v = NULL)`GEN `

is also
available.**vecmin**(GEN x)