Standard monadic or dyadic operators


GP operators

Loosely speaking, an operator is a function, usually attached to basic arithmetic operations, whose name contains only non-alphanumeric characters. For instance + or -, but also = or += , or even [ ] (the selection operator). As all functions, operators take arguments, and return a value; assignment operators also have side effects: besides returning a value, they change the value of some variable.

Each operator has a fixed and unchangeable priority, which means that, in a given expression, the operations with the highest priority is performed first. Unless mentioned otherwise, operators at the same priority level are left-associative (performed from left to right), unless they are assignments, in which case they are right-associative. Anything enclosed between parenthesis is considered a complete subexpression, and is resolved recursively, independently of the surrounding context. For instance,

    a + b + c    -->   (a + b) + c     \\  left-associative
    a = b = c    -->   a = (b = c)     \\  right-associative

Assuming that op1, op2, op3 are binary operators with increasing priorities (think of +, *, ^), x op1 y op2 z op2 x op3 y is equivalent to x op1 ((y op2 z) op2  (x op3 y)).

GP contains many different operators, either unary (having only one argument) or binary, plus a few special selection operators. Unary operators are defined as either prefix or postfix, meaning that they respectively precede (op x) and follow (x op) their single argument. Some symbols are syntactically correct in both positions, like !, but then represent different operators: the ! symbol represents the negation and factorial operators when in prefix and postfix position respectively. Binary operators all use the (infix) syntax x op y.

Most operators are standard (+, %, = ), some are borrowed from the C language (++, << ), and a few are specific to GP (\, #). Beware that some GP operators differ slightly from their C counterparts. For instance, GP's postfix ++ returns the new value, like the prefix ++ of C, and the binary shifts << , >> have a priority which is different from (higher than) that of their C counterparts. When in doubt, just surround everything by parentheses; besides, your code will be more legible.

Here is the list of available operators, ordered by decreasing priority, binary and left-associative unless mentioned otherwise. An expression is an lvalue if something can be assigned to it. (The name comes from left-value, to the left of a = operator; e.g. x, or v[1] are lvalues, but x + 1 is not.)

* Priority 14

: as in x:small, is used to indicate to the GP2C compiler that the variable on the left-hand side always contains objects of the type specified on the right hand-side (here, a small integer) in order to produce more efficient or more readable C code. This is ignored by GP.

* Priority 13 ( ) is the function call operator. If f is a closure and args is a comma-separated list of arguments (possibly empty), f(args) evaluates f on those arguments.

* Priority 12

++ and -- (unary, postfix): if x is an lvalue, x++ assigns the value x+1 to x, then returns the new value of x. This corresponds to the C statement ++x: there is no prefix ++ operator in GP. x-- does the same with x-1. These operators are not associative, i.e. x++++ is invalid, since x++ is not an lvalue.

* Priority 11

.member (unary, postfix): x.member extracts member from structure x (see Section se:member).

[ ] is the selection operator. x[i] returns the i-th component of vector x; x[i,j], x[,j] and x[i,] respectively return the entry of coordinates (i,j), the j-th column, and the i-th row of matrix x. If the assignment operator ( = ) immediately follows a sequence of selections, it assigns its right hand side to the selected component. E.g x[1][1] = 0 is valid; but beware that (x[1])[1] = 0 is not (because the parentheses force the complete evaluation of x[1], and the result is not modifiable).

* Priority 10

' (unary, postfix): derivative with respect to the main variable. If f is a function (tCLOSURE), f' is allowed and defines a new function, which will perform numerical derivation when evaluated at a scalar x; this is defined as (f(x+ϵ) - f(x-ϵ)) / 2ϵ for a suitably small epsilon depending on current precision.

  ? (x2 + y*x + y2)'  \\  derive with respect to main variable x
  %1 = 2*x + y
  ? SIN = cos'
  %2 = cos'
  ? SIN(Pi/6)         \\  numerical derivation
  %3 = -0.5000000000000000000000000000
  ? cos'(Pi/6)        \\  works directly: no need for intermediate SIN
  %4 = -0.5000000000000000000000000000

~ (unary, postfix): vector/matrix transpose.

! (unary, postfix): factorial. x! = x(x-1)...1.

! (unary, prefix): logical not. !x returns 1 if x is equal to 0 (specifically, if gequal0(x) == 1), and 0 otherwise.

* Priority 9

# (unary, prefix): cardinality; #x returns length(x).

* Priority 8

^: powering. This operator is right associative: 234 is understood as 2^(34).

* Priority 7

+, - (unary, prefix): - toggles the sign of its argument, + has no effect whatsoever.

* Priority 6

*: multiplication.

/: exact division (3/2 yields 3/2, not 1.5).

\, %: Euclidean quotient and remainder, i.e. if x = qy + r, then x \ y = q, x%y = r. If x and y are scalars, then q is an integer and r satisfies 0 ≤ r < |y|; if x and y are polynomials, then q and r are polynomials such that deg r < deg y and the leading terms of r and x have the same sign.

\/: rounded Euclidean quotient for integers (rounded towards + oo when the exact quotient would be a half-integer).

<< , >> : left and right binary shift. By definition, x << n  =  x * 2n if n > 0, and truncate(x 2-n) otherwise. Right shift is defined by x >> n  =  x << (-n).

* Priority 5

+, -: addition/subtraction.

* Priority 4

< , > , <= , >= : the usual comparison operators, returning 1 for true and 0 for false. For instance, x <= 1 returns 1 if x ≤ 1 and 0 otherwise.

<> , != : test for (exact) inequality.

== : test for (exact) equality. tQFR having the same coefficients but a different distance component are tested as equal.

=== : test whether two objects are identical component-wise. This is stricter than == : for instance, the integer 0, a 0 polynomial or a vector with 0 entries, are all tested equal by == , but they are not identical.

* Priority 3

&&: logical and.

||: logical (inclusive) or. Any sequence of logical or and and operations is evaluated from left to right, and aborted as soon as the final truth value is known. Thus, for instance,

    x == 0 || test(1/x)

will never produce an error since test(1/x) is not even evaluated when the first test is true (hence the final truth value is true). Similarly

    type(p) == "tINT" && isprime(p)

does not evaluate isprime(p) if p is not an integer.

* Priority 2

= (assignment, lvalue = expr). The result of x  =  y is the value of the expression y, which is also assigned to the variable x. This assignment operator is right-associative. This is not the equality test operator; a statement like x  =  1 is always true (i.e. non-zero), and sets x to 1; the equality test would be x == 1. The right hand side of the assignment operator is evaluated before the left hand side.

It is crucial that the left hand-side be an lvalue there, it avoids ambiguities in expressions like 1 + x = 1. The latter evaluates as 1 + (x = 1), not as (1 + x) = 1, even though the priority of = is lower than the priority of +: 1 + x is not an lvalue.

If the expression cannot be parsed in a way where the left hand side is an lvalue, raise an error.

  ? x + 1 = 1
    ***   syntax error, unexpected '=', expecting $end or ';': x+1=1
    ***                                                           ^--

op = , where op is any binary operator among +, -, *, %, /, \, \/, << , or >> (composed assignment lvalue op = expr). The expression op =  y assigns (x op y) to x, and returns the new value of x. The result is not an lvalue; thus

    (x += 2) = 3

is invalid. These assignment operators are right-associative:

    ? x = 'x; x += x *= 2
    %1 = 3*x

* Priority 1 - > (function definition): (vars)- > expr returns a function object, of type tCLOSURE.

Remark. Use the op = operators as often as possible since they make complex assignments more legible: one needs not parse complicated expressions twice to make sure they are indeed identical. Compare

  v[i+j-1] = v[i+j-1] + 1    -->    v[i+j-1]++
  
  M[i,i+j] = M[i,i+j] * 2    -->    M[i,i+j] *= 2

Remark. Less important but still interesting. The ++, -- and op = operators are slightly more efficient:

  ? a = 106;
  ? i = 0; while(i<a, i=i+1)
  time = 365 ms.
  ? i = 0; while(i<a, i++)
  time = 352 ms.

For the same reason, the shift operators should be preferred to multiplication:

  ? a = 1<<(105);
  ? i = 1; while(i<a, i=i*2);
  time = 1,052 ms.
  ? i = 1; while(i<a, i<<=1);
  time = 617 ms.


GP operators

Loosely speaking, an operator is a function, usually attached to basic arithmetic operations, whose name contains only non-alphanumeric characters. For instance + or -, but also = or += , or even [ ] (the selection operator). As all functions, operators take arguments, and return a value; assignment operators also have side effects: besides returning a value, they change the value of some variable.

Each operator has a fixed and unchangeable priority, which means that, in a given expression, the operations with the highest priority is performed first. Unless mentioned otherwise, operators at the same priority level are left-associative (performed from left to right), unless they are assignments, in which case they are right-associative. Anything enclosed between parenthesis is considered a complete subexpression, and is resolved recursively, independently of the surrounding context. For instance,

    a + b + c    -->   (a + b) + c     \\  left-associative
    a = b = c    -->   a = (b = c)     \\  right-associative

Assuming that op1, op2, op3 are binary operators with increasing priorities (think of +, *, ^), x op1 y op2 z op2 x op3 y is equivalent to x op1 ((y op2 z) op2  (x op3 y)).

GP contains many different operators, either unary (having only one argument) or binary, plus a few special selection operators. Unary operators are defined as either prefix or postfix, meaning that they respectively precede (op x) and follow (x op) their single argument. Some symbols are syntactically correct in both positions, like !, but then represent different operators: the ! symbol represents the negation and factorial operators when in prefix and postfix position respectively. Binary operators all use the (infix) syntax x op y.

Most operators are standard (+, %, = ), some are borrowed from the C language (++, << ), and a few are specific to GP (\, #). Beware that some GP operators differ slightly from their C counterparts. For instance, GP's postfix ++ returns the new value, like the prefix ++ of C, and the binary shifts << , >> have a priority which is different from (higher than) that of their C counterparts. When in doubt, just surround everything by parentheses; besides, your code will be more legible.

Here is the list of available operators, ordered by decreasing priority, binary and left-associative unless mentioned otherwise. An expression is an lvalue if something can be assigned to it. (The name comes from left-value, to the left of a = operator; e.g. x, or v[1] are lvalues, but x + 1 is not.)

* Priority 14

: as in x:small, is used to indicate to the GP2C compiler that the variable on the left-hand side always contains objects of the type specified on the right hand-side (here, a small integer) in order to produce more efficient or more readable C code. This is ignored by GP.

* Priority 13 ( ) is the function call operator. If f is a closure and args is a comma-separated list of arguments (possibly empty), f(args) evaluates f on those arguments.

* Priority 12

++ and -- (unary, postfix): if x is an lvalue, x++ assigns the value x+1 to x, then returns the new value of x. This corresponds to the C statement ++x: there is no prefix ++ operator in GP. x-- does the same with x-1. These operators are not associative, i.e. x++++ is invalid, since x++ is not an lvalue.

* Priority 11

.member (unary, postfix): x.member extracts member from structure x (see Section se:member).

[ ] is the selection operator. x[i] returns the i-th component of vector x; x[i,j], x[,j] and x[i,] respectively return the entry of coordinates (i,j), the j-th column, and the i-th row of matrix x. If the assignment operator ( = ) immediately follows a sequence of selections, it assigns its right hand side to the selected component. E.g x[1][1] = 0 is valid; but beware that (x[1])[1] = 0 is not (because the parentheses force the complete evaluation of x[1], and the result is not modifiable).

* Priority 10

' (unary, postfix): derivative with respect to the main variable. If f is a function (tCLOSURE), f' is allowed and defines a new function, which will perform numerical derivation when evaluated at a scalar x; this is defined as (f(x+ϵ) - f(x-ϵ)) / 2ϵ for a suitably small epsilon depending on current precision.

  ? (x2 + y*x + y2)'  \\  derive with respect to main variable x
  %1 = 2*x + y
  ? SIN = cos'
  %2 = cos'
  ? SIN(Pi/6)         \\  numerical derivation
  %3 = -0.5000000000000000000000000000
  ? cos'(Pi/6)        \\  works directly: no need for intermediate SIN
  %4 = -0.5000000000000000000000000000

~ (unary, postfix): vector/matrix transpose.

! (unary, postfix): factorial. x! = x(x-1)...1.

! (unary, prefix): logical not. !x returns 1 if x is equal to 0 (specifically, if gequal0(x) == 1), and 0 otherwise.

* Priority 9

# (unary, prefix): cardinality; #x returns length(x).

* Priority 8

^: powering. This operator is right associative: 234 is understood as 2^(34).

* Priority 7

+, - (unary, prefix): - toggles the sign of its argument, + has no effect whatsoever.

* Priority 6

*: multiplication.

/: exact division (3/2 yields 3/2, not 1.5).

\, %: Euclidean quotient and remainder, i.e. if x = qy + r, then x \ y = q, x%y = r. If x and y are scalars, then q is an integer and r satisfies 0 ≤ r < |y|; if x and y are polynomials, then q and r are polynomials such that deg r < deg y and the leading terms of r and x have the same sign.

\/: rounded Euclidean quotient for integers (rounded towards + oo when the exact quotient would be a half-integer).

<< , >> : left and right binary shift. By definition, x << n  =  x * 2n if n > 0, and truncate(x 2-n) otherwise. Right shift is defined by x >> n  =  x << (-n).

* Priority 5

+, -: addition/subtraction.

* Priority 4

< , > , <= , >= : the usual comparison operators, returning 1 for true and 0 for false. For instance, x <= 1 returns 1 if x ≤ 1 and 0 otherwise.

<> , != : test for (exact) inequality.

== : test for (exact) equality. tQFR having the same coefficients but a different distance component are tested as equal.

=== : test whether two objects are identical component-wise. This is stricter than == : for instance, the integer 0, a 0 polynomial or a vector with 0 entries, are all tested equal by == , but they are not identical.

* Priority 3

&&: logical and.

||: logical (inclusive) or. Any sequence of logical or and and operations is evaluated from left to right, and aborted as soon as the final truth value is known. Thus, for instance,

    x == 0 || test(1/x)

will never produce an error since test(1/x) is not even evaluated when the first test is true (hence the final truth value is true). Similarly

    type(p) == "tINT" && isprime(p)

does not evaluate isprime(p) if p is not an integer.

* Priority 2

= (assignment, lvalue = expr). The result of x  =  y is the value of the expression y, which is also assigned to the variable x. This assignment operator is right-associative. This is not the equality test operator; a statement like x  =  1 is always true (i.e. non-zero), and sets x to 1; the equality test would be x == 1. The right hand side of the assignment operator is evaluated before the left hand side.

It is crucial that the left hand-side be an lvalue there, it avoids ambiguities in expressions like 1 + x = 1. The latter evaluates as 1 + (x = 1), not as (1 + x) = 1, even though the priority of = is lower than the priority of +: 1 + x is not an lvalue.

If the expression cannot be parsed in a way where the left hand side is an lvalue, raise an error.

  ? x + 1 = 1
    ***   syntax error, unexpected '=', expecting $end or ';': x+1=1
    ***                                                           ^--

op = , where op is any binary operator among +, -, *, %, /, \, \/, << , or >> (composed assignment lvalue op = expr). The expression op =  y assigns (x op y) to x, and returns the new value of x. The result is not an lvalue; thus

    (x += 2) = 3

is invalid. These assignment operators are right-associative:

    ? x = 'x; x += x *= 2
    %1 = 3*x

* Priority 1 - > (function definition): (vars)- > expr returns a function object, of type tCLOSURE.

Remark. Use the op = operators as often as possible since they make complex assignments more legible: one needs not parse complicated expressions twice to make sure they are indeed identical. Compare

  v[i+j-1] = v[i+j-1] + 1    -->    v[i+j-1]++
  
  M[i,i+j] = M[i,i+j] * 2    -->    M[i,i+j] *= 2

Remark. Less important but still interesting. The ++, -- and op = operators are slightly more efficient:

  ? a = 106;
  ? i = 0; while(i<a, i=i+1)
  time = 365 ms.
  ? i = 0; while(i<a, i++)
  time = 352 ms.

For the same reason, the shift operators should be preferred to multiplication:

  ? a = 1<<(105);
  ? i = 1; while(i<a, i=i*2);
  time = 1,052 ms.
  ? i = 1; while(i<a, i<<=1);
  time = 617 ms.


GP operators

Loosely speaking, an operator is a function, usually attached to basic arithmetic operations, whose name contains only non-alphanumeric characters. For instance + or -, but also = or += , or even [ ] (the selection operator). As all functions, operators take arguments, and return a value; assignment operators also have side effects: besides returning a value, they change the value of some variable.

Each operator has a fixed and unchangeable priority, which means that, in a given expression, the operations with the highest priority is performed first. Unless mentioned otherwise, operators at the same priority level are left-associative (performed from left to right), unless they are assignments, in which case they are right-associative. Anything enclosed between parenthesis is considered a complete subexpression, and is resolved recursively, independently of the surrounding context. For instance,

    a + b + c    -->   (a + b) + c     \\  left-associative
    a = b = c    -->   a = (b = c)     \\  right-associative

Assuming that op1, op2, op3 are binary operators with increasing priorities (think of +, *, ^), x op1 y op2 z op2 x op3 y is equivalent to x op1 ((y op2 z) op2  (x op3 y)).

GP contains many different operators, either unary (having only one argument) or binary, plus a few special selection operators. Unary operators are defined as either prefix or postfix, meaning that they respectively precede (op x) and follow (x op) their single argument. Some symbols are syntactically correct in both positions, like !, but then represent different operators: the ! symbol represents the negation and factorial operators when in prefix and postfix position respectively. Binary operators all use the (infix) syntax x op y.

Most operators are standard (+, %, = ), some are borrowed from the C language (++, << ), and a few are specific to GP (\, #). Beware that some GP operators differ slightly from their C counterparts. For instance, GP's postfix ++ returns the new value, like the prefix ++ of C, and the binary shifts << , >> have a priority which is different from (higher than) that of their C counterparts. When in doubt, just surround everything by parentheses; besides, your code will be more legible.

Here is the list of available operators, ordered by decreasing priority, binary and left-associative unless mentioned otherwise. An expression is an lvalue if something can be assigned to it. (The name comes from left-value, to the left of a = operator; e.g. x, or v[1] are lvalues, but x + 1 is not.)

* Priority 14

: as in x:small, is used to indicate to the GP2C compiler that the variable on the left-hand side always contains objects of the type specified on the right hand-side (here, a small integer) in order to produce more efficient or more readable C code. This is ignored by GP.

* Priority 13 ( ) is the function call operator. If f is a closure and args is a comma-separated list of arguments (possibly empty), f(args) evaluates f on those arguments.

* Priority 12

++ and -- (unary, postfix): if x is an lvalue, x++ assigns the value x+1 to x, then returns the new value of x. This corresponds to the C statement ++x: there is no prefix ++ operator in GP. x-- does the same with x-1. These operators are not associative, i.e. x++++ is invalid, since x++ is not an lvalue.

* Priority 11

.member (unary, postfix): x.member extracts member from structure x (see Section se:member).

[ ] is the selection operator. x[i] returns the i-th component of vector x; x[i,j], x[,j] and x[i,] respectively return the entry of coordinates (i,j), the j-th column, and the i-th row of matrix x. If the assignment operator ( = ) immediately follows a sequence of selections, it assigns its right hand side to the selected component. E.g x[1][1] = 0 is valid; but beware that (x[1])[1] = 0 is not (because the parentheses force the complete evaluation of x[1], and the result is not modifiable).

* Priority 10

' (unary, postfix): derivative with respect to the main variable. If f is a function (tCLOSURE), f' is allowed and defines a new function, which will perform numerical derivation when evaluated at a scalar x; this is defined as (f(x+ϵ) - f(x-ϵ)) / 2ϵ for a suitably small epsilon depending on current precision.

  ? (x2 + y*x + y2)'  \\  derive with respect to main variable x
  %1 = 2*x + y
  ? SIN = cos'
  %2 = cos'
  ? SIN(Pi/6)         \\  numerical derivation
  %3 = -0.5000000000000000000000000000
  ? cos'(Pi/6)        \\  works directly: no need for intermediate SIN
  %4 = -0.5000000000000000000000000000

~ (unary, postfix): vector/matrix transpose.

! (unary, postfix): factorial. x! = x(x-1)...1.

! (unary, prefix): logical not. !x returns 1 if x is equal to 0 (specifically, if gequal0(x) == 1), and 0 otherwise.

* Priority 9

# (unary, prefix): cardinality; #x returns length(x).

* Priority 8

^: powering. This operator is right associative: 234 is understood as 2^(34).

* Priority 7

+, - (unary, prefix): - toggles the sign of its argument, + has no effect whatsoever.

* Priority 6

*: multiplication.

/: exact division (3/2 yields 3/2, not 1.5).

\, %: Euclidean quotient and remainder, i.e. if x = qy + r, then x \ y = q, x%y = r. If x and y are scalars, then q is an integer and r satisfies 0 ≤ r < |y|; if x and y are polynomials, then q and r are polynomials such that deg r < deg y and the leading terms of r and x have the same sign.

\/: rounded Euclidean quotient for integers (rounded towards + oo when the exact quotient would be a half-integer).

<< , >> : left and right binary shift. By definition, x << n  =  x * 2n if n > 0, and truncate(x 2-n) otherwise. Right shift is defined by x >> n  =  x << (-n).

* Priority 5

+, -: addition/subtraction.

* Priority 4

< , > , <= , >= : the usual comparison operators, returning 1 for true and 0 for false. For instance, x <= 1 returns 1 if x ≤ 1 and 0 otherwise.

<> , != : test for (exact) inequality.

== : test for (exact) equality. tQFR having the same coefficients but a different distance component are tested as equal.

=== : test whether two objects are identical component-wise. This is stricter than == : for instance, the integer 0, a 0 polynomial or a vector with 0 entries, are all tested equal by == , but they are not identical.

* Priority 3

&&: logical and.

||: logical (inclusive) or. Any sequence of logical or and and operations is evaluated from left to right, and aborted as soon as the final truth value is known. Thus, for instance,

    x == 0 || test(1/x)

will never produce an error since test(1/x) is not even evaluated when the first test is true (hence the final truth value is true). Similarly

    type(p) == "tINT" && isprime(p)

does not evaluate isprime(p) if p is not an integer.

* Priority 2

= (assignment, lvalue = expr). The result of x  =  y is the value of the expression y, which is also assigned to the variable x. This assignment operator is right-associative. This is not the equality test operator; a statement like x  =  1 is always true (i.e. non-zero), and sets x to 1; the equality test would be x == 1. The right hand side of the assignment operator is evaluated before the left hand side.

It is crucial that the left hand-side be an lvalue there, it avoids ambiguities in expressions like 1 + x = 1. The latter evaluates as 1 + (x = 1), not as (1 + x) = 1, even though the priority of = is lower than the priority of +: 1 + x is not an lvalue.

If the expression cannot be parsed in a way where the left hand side is an lvalue, raise an error.

  ? x + 1 = 1
    ***   syntax error, unexpected '=', expecting $end or ';': x+1=1
    ***                                                           ^--

op = , where op is any binary operator among +, -, *, %, /, \, \/, << , or >> (composed assignment lvalue op = expr). The expression op =  y assigns (x op y) to x, and returns the new value of x. The result is not an lvalue; thus

    (x += 2) = 3

is invalid. These assignment operators are right-associative:

    ? x = 'x; x += x *= 2
    %1 = 3*x

* Priority 1 - > (function definition): (vars)- > expr returns a function object, of type tCLOSURE.

Remark. Use the op = operators as often as possible since they make complex assignments more legible: one needs not parse complicated expressions twice to make sure they are indeed identical. Compare

  v[i+j-1] = v[i+j-1] + 1    -->    v[i+j-1]++
  
  M[i,i+j] = M[i,i+j] * 2    -->    M[i,i+j] *= 2

Remark. Less important but still interesting. The ++, -- and op = operators are slightly more efficient:

  ? a = 106;
  ? i = 0; while(i<a, i=i+1)
  time = 365 ms.
  ? i = 0; while(i<a, i++)
  time = 352 ms.

For the same reason, the shift operators should be preferred to multiplication:

  ? a = 1<<(105);
  ? i = 1; while(i<a, i=i*2);
  time = 1,052 ms.
  ? i = 1; while(i<a, i<<=1);
  time = 617 ms.


GP operators

Loosely speaking, an operator is a function, usually attached to basic arithmetic operations, whose name contains only non-alphanumeric characters. For instance + or -, but also = or += , or even [ ] (the selection operator). As all functions, operators take arguments, and return a value; assignment operators also have side effects: besides returning a value, they change the value of some variable.

Each operator has a fixed and unchangeable priority, which means that, in a given expression, the operations with the highest priority is performed first. Unless mentioned otherwise, operators at the same priority level are left-associative (performed from left to right), unless they are assignments, in which case they are right-associative. Anything enclosed between parenthesis is considered a complete subexpression, and is resolved recursively, independently of the surrounding context. For instance,

    a + b + c    -->   (a + b) + c     \\  left-associative
    a = b = c    -->   a = (b = c)     \\  right-associative

Assuming that op1, op2, op3 are binary operators with increasing priorities (think of +, *, ^), x op1 y op2 z op2 x op3 y is equivalent to x op1 ((y op2 z) op2  (x op3 y)).

GP contains many different operators, either unary (having only one argument) or binary, plus a few special selection operators. Unary operators are defined as either prefix or postfix, meaning that they respectively precede (op x) and follow (x op) their single argument. Some symbols are syntactically correct in both positions, like !, but then represent different operators: the ! symbol represents the negation and factorial operators when in prefix and postfix position respectively. Binary operators all use the (infix) syntax x op y.

Most operators are standard (+, %, = ), some are borrowed from the C language (++, << ), and a few are specific to GP (\, #). Beware that some GP operators differ slightly from their C counterparts. For instance, GP's postfix ++ returns the new value, like the prefix ++ of C, and the binary shifts << , >> have a priority which is different from (higher than) that of their C counterparts. When in doubt, just surround everything by parentheses; besides, your code will be more legible.

Here is the list of available operators, ordered by decreasing priority, binary and left-associative unless mentioned otherwise. An expression is an lvalue if something can be assigned to it. (The name comes from left-value, to the left of a = operator; e.g. x, or v[1] are lvalues, but x + 1 is not.)

* Priority 14

: as in x:small, is used to indicate to the GP2C compiler that the variable on the left-hand side always contains objects of the type specified on the right hand-side (here, a small integer) in order to produce more efficient or more readable C code. This is ignored by GP.

* Priority 13 ( ) is the function call operator. If f is a closure and args is a comma-separated list of arguments (possibly empty), f(args) evaluates f on those arguments.

* Priority 12

++ and -- (unary, postfix): if x is an lvalue, x++ assigns the value x+1 to x, then returns the new value of x. This corresponds to the C statement ++x: there is no prefix ++ operator in GP. x-- does the same with x-1. These operators are not associative, i.e. x++++ is invalid, since x++ is not an lvalue.

* Priority 11

.member (unary, postfix): x.member extracts member from structure x (see Section se:member).

[ ] is the selection operator. x[i] returns the i-th component of vector x; x[i,j], x[,j] and x[i,] respectively return the entry of coordinates (i,j), the j-th column, and the i-th row of matrix x. If the assignment operator ( = ) immediately follows a sequence of selections, it assigns its right hand side to the selected component. E.g x[1][1] = 0 is valid; but beware that (x[1])[1] = 0 is not (because the parentheses force the complete evaluation of x[1], and the result is not modifiable).

* Priority 10

' (unary, postfix): derivative with respect to the main variable. If f is a function (tCLOSURE), f' is allowed and defines a new function, which will perform numerical derivation when evaluated at a scalar x; this is defined as (f(x+ϵ) - f(x-ϵ)) / 2ϵ for a suitably small epsilon depending on current precision.

  ? (x2 + y*x + y2)'  \\  derive with respect to main variable x
  %1 = 2*x + y
  ? SIN = cos'
  %2 = cos'
  ? SIN(Pi/6)         \\  numerical derivation
  %3 = -0.5000000000000000000000000000
  ? cos'(Pi/6)        \\  works directly: no need for intermediate SIN
  %4 = -0.5000000000000000000000000000

~ (unary, postfix): vector/matrix transpose.

! (unary, postfix): factorial. x! = x(x-1)...1.

! (unary, prefix): logical not. !x returns 1 if x is equal to 0 (specifically, if gequal0(x) == 1), and 0 otherwise.

* Priority 9

# (unary, prefix): cardinality; #x returns length(x).

* Priority 8

^: powering. This operator is right associative: 234 is understood as 2^(34).

* Priority 7

+, - (unary, prefix): - toggles the sign of its argument, + has no effect whatsoever.

* Priority 6

*: multiplication.

/: exact division (3/2 yields 3/2, not 1.5).

\, %: Euclidean quotient and remainder, i.e. if x = qy + r, then x \ y = q, x%y = r. If x and y are scalars, then q is an integer and r satisfies 0 ≤ r < |y|; if x and y are polynomials, then q and r are polynomials such that deg r < deg y and the leading terms of r and x have the same sign.

\/: rounded Euclidean quotient for integers (rounded towards + oo when the exact quotient would be a half-integer).

<< , >> : left and right binary shift. By definition, x << n  =  x * 2n if n > 0, and truncate(x 2-n) otherwise. Right shift is defined by x >> n  =  x << (-n).

* Priority 5

+, -: addition/subtraction.

* Priority 4

< , > , <= , >= : the usual comparison operators, returning 1 for true and 0 for false. For instance, x <= 1 returns 1 if x ≤ 1 and 0 otherwise.

<> , != : test for (exact) inequality.

== : test for (exact) equality. tQFR having the same coefficients but a different distance component are tested as equal.

=== : test whether two objects are identical component-wise. This is stricter than == : for instance, the integer 0, a 0 polynomial or a vector with 0 entries, are all tested equal by == , but they are not identical.

* Priority 3

&&: logical and.

||: logical (inclusive) or. Any sequence of logical or and and operations is evaluated from left to right, and aborted as soon as the final truth value is known. Thus, for instance,

    x == 0 || test(1/x)

will never produce an error since test(1/x) is not even evaluated when the first test is true (hence the final truth value is true). Similarly

    type(p) == "tINT" && isprime(p)

does not evaluate isprime(p) if p is not an integer.

* Priority 2

= (assignment, lvalue = expr). The result of x  =  y is the value of the expression y, which is also assigned to the variable x. This assignment operator is right-associative. This is not the equality test operator; a statement like x  =  1 is always true (i.e. non-zero), and sets x to 1; the equality test would be x == 1. The right hand side of the assignment operator is evaluated before the left hand side.

It is crucial that the left hand-side be an lvalue there, it avoids ambiguities in expressions like 1 + x = 1. The latter evaluates as 1 + (x = 1), not as (1 + x) = 1, even though the priority of = is lower than the priority of +: 1 + x is not an lvalue.

If the expression cannot be parsed in a way where the left hand side is an lvalue, raise an error.

  ? x + 1 = 1
    ***   syntax error, unexpected '=', expecting $end or ';': x+1=1
    ***                                                           ^--

op = , where op is any binary operator among +, -, *, %, /, \, \/, << , or >> (composed assignment lvalue op = expr). The expression op =  y assigns (x op y) to x, and returns the new value of x. The result is not an lvalue; thus

    (x += 2) = 3

is invalid. These assignment operators are right-associative:

    ? x = 'x; x += x *= 2
    %1 = 3*x

* Priority 1 - > (function definition): (vars)- > expr returns a function object, of type tCLOSURE.

Remark. Use the op = operators as often as possible since they make complex assignments more legible: one needs not parse complicated expressions twice to make sure they are indeed identical. Compare

  v[i+j-1] = v[i+j-1] + 1    -->    v[i+j-1]++
  
  M[i,i+j] = M[i,i+j] * 2    -->    M[i,i+j] *= 2

Remark. Less important but still interesting. The ++, -- and op = operators are slightly more efficient:

  ? a = 106;
  ? i = 0; while(i<a, i=i+1)
  time = 365 ms.
  ? i = 0; while(i<a, i++)
  time = 352 ms.

For the same reason, the shift operators should be preferred to multiplication:

  ? a = 1<<(105);
  ? i = 1; while(i<a, i=i*2);
  time = 1,052 ms.
  ? i = 1; while(i<a, i<<=1);
  time = 617 ms.


GP operators

Loosely speaking, an operator is a function, usually attached to basic arithmetic operations, whose name contains only non-alphanumeric characters. For instance + or -, but also = or += , or even [ ] (the selection operator). As all functions, operators take arguments, and return a value; assignment operators also have side effects: besides returning a value, they change the value of some variable.

Each operator has a fixed and unchangeable priority, which means that, in a given expression, the operations with the highest priority is performed first. Unless mentioned otherwise, operators at the same priority level are left-associative (performed from left to right), unless they are assignments, in which case they are right-associative. Anything enclosed between parenthesis is considered a complete subexpression, and is resolved recursively, independently of the surrounding context. For instance,

    a + b + c    -->   (a + b) + c     \\  left-associative
    a = b = c    -->   a = (b = c)     \\  right-associative

Assuming that op1, op2, op3 are binary operators with increasing priorities (think of +, *, ^), x op1 y op2 z op2 x op3 y is equivalent to x op1 ((y op2 z) op2  (x op3 y)).

GP contains many different operators, either unary (having only one argument) or binary, plus a few special selection operators. Unary operators are defined as either prefix or postfix, meaning that they respectively precede (op x) and follow (x op) their single argument. Some symbols are syntactically correct in both positions, like !, but then represent different operators: the ! symbol represents the negation and factorial operators when in prefix and postfix position respectively. Binary operators all use the (infix) syntax x op y.

Most operators are standard (+, %, = ), some are borrowed from the C language (++, << ), and a few are specific to GP (\, #). Beware that some GP operators differ slightly from their C counterparts. For instance, GP's postfix ++ returns the new value, like the prefix ++ of C, and the binary shifts << , >> have a priority which is different from (higher than) that of their C counterparts. When in doubt, just surround everything by parentheses; besides, your code will be more legible.

Here is the list of available operators, ordered by decreasing priority, binary and left-associative unless mentioned otherwise. An expression is an lvalue if something can be assigned to it. (The name comes from left-value, to the left of a = operator; e.g. x, or v[1] are lvalues, but x + 1 is not.)

* Priority 14

: as in x:small, is used to indicate to the GP2C compiler that the variable on the left-hand side always contains objects of the type specified on the right hand-side (here, a small integer) in order to produce more efficient or more readable C code. This is ignored by GP.

* Priority 13 ( ) is the function call operator. If f is a closure and args is a comma-separated list of arguments (possibly empty), f(args) evaluates f on those arguments.

* Priority 12

++ and -- (unary, postfix): if x is an lvalue, x++ assigns the value x+1 to x, then returns the new value of x. This corresponds to the C statement ++x: there is no prefix ++ operator in GP. x-- does the same with x-1. These operators are not associative, i.e. x++++ is invalid, since x++ is not an lvalue.

* Priority 11

.member (unary, postfix): x.member extracts member from structure x (see Section se:member).

[ ] is the selection operator. x[i] returns the i-th component of vector x; x[i,j], x[,j] and x[i,] respectively return the entry of coordinates (i,j), the j-th column, and the i-th row of matrix x. If the assignment operator ( = ) immediately follows a sequence of selections, it assigns its right hand side to the selected component. E.g x[1][1] = 0 is valid; but beware that (x[1])[1] = 0 is not (because the parentheses force the complete evaluation of x[1], and the result is not modifiable).

* Priority 10

' (unary, postfix): derivative with respect to the main variable. If f is a function (tCLOSURE), f' is allowed and defines a new function, which will perform numerical derivation when evaluated at a scalar x; this is defined as (f(x+ϵ) - f(x-ϵ)) / 2ϵ for a suitably small epsilon depending on current precision.

  ? (x2 + y*x + y2)'  \\  derive with respect to main variable x
  %1 = 2*x + y
  ? SIN = cos'
  %2 = cos'
  ? SIN(Pi/6)         \\  numerical derivation
  %3 = -0.5000000000000000000000000000
  ? cos'(Pi/6)        \\  works directly: no need for intermediate SIN
  %4 = -0.5000000000000000000000000000

~ (unary, postfix): vector/matrix transpose.

! (unary, postfix): factorial. x! = x(x-1)...1.

! (unary, prefix): logical not. !x returns 1 if x is equal to 0 (specifically, if gequal0(x) == 1), and 0 otherwise.

* Priority 9

# (unary, prefix): cardinality; #x returns length(x).

* Priority 8

^: powering. This operator is right associative: 234 is understood as 2^(34).

* Priority 7

+, - (unary, prefix): - toggles the sign of its argument, + has no effect whatsoever.

* Priority 6

*: multiplication.

/: exact division (3/2 yields 3/2, not 1.5).

\, %: Euclidean quotient and remainder, i.e. if x = qy + r, then x \ y = q, x%y = r. If x and y are scalars, then q is an integer and r satisfies 0 ≤ r < |y|; if x and y are polynomials, then q and r are polynomials such that deg r < deg y and the leading terms of r and x have the same sign.

\/: rounded Euclidean quotient for integers (rounded towards + oo when the exact quotient would be a half-integer).

<< , >> : left and right binary shift. By definition, x << n  =  x * 2n if n > 0, and truncate(x 2-n) otherwise. Right shift is defined by x >> n  =  x << (-n).

* Priority 5

+, -: addition/subtraction.

* Priority 4

< , > , <= , >= : the usual comparison operators, returning 1 for true and 0 for false. For instance, x <= 1 returns 1 if x ≤ 1 and 0 otherwise.

<> , != : test for (exact) inequality.

== : test for (exact) equality. tQFR having the same coefficients but a different distance component are tested as equal.

=== : test whether two objects are identical component-wise. This is stricter than == : for instance, the integer 0, a 0 polynomial or a vector with 0 entries, are all tested equal by == , but they are not identical.

* Priority 3

&&: logical and.

||: logical (inclusive) or. Any sequence of logical or and and operations is evaluated from left to right, and aborted as soon as the final truth value is known. Thus, for instance,

    x == 0 || test(1/x)

will never produce an error since test(1/x) is not even evaluated when the first test is true (hence the final truth value is true). Similarly

    type(p) == "tINT" && isprime(p)

does not evaluate isprime(p) if p is not an integer.

* Priority 2

= (assignment, lvalue = expr). The result of x  =  y is the value of the expression y, which is also assigned to the variable x. This assignment operator is right-associative. This is not the equality test operator; a statement like x  =  1 is always true (i.e. non-zero), and sets x to 1; the equality test would be x == 1. The right hand side of the assignment operator is evaluated before the left hand side.

It is crucial that the left hand-side be an lvalue there, it avoids ambiguities in expressions like 1 + x = 1. The latter evaluates as 1 + (x = 1), not as (1 + x) = 1, even though the priority of = is lower than the priority of +: 1 + x is not an lvalue.

If the expression cannot be parsed in a way where the left hand side is an lvalue, raise an error.

  ? x + 1 = 1
    ***   syntax error, unexpected '=', expecting $end or ';': x+1=1
    ***                                                           ^--

op = , where op is any binary operator among +, -, *, %, /, \, \/, << , or >> (composed assignment lvalue op = expr). The expression op =  y assigns (x op y) to x, and returns the new value of x. The result is not an lvalue; thus

    (x += 2) = 3

is invalid. These assignment operators are right-associative:

    ? x = 'x; x += x *= 2
    %1 = 3*x

* Priority 1 - > (function definition): (vars)- > expr returns a function object, of type tCLOSURE.

Remark. Use the op = operators as often as possible since they make complex assignments more legible: one needs not parse complicated expressions twice to make sure they are indeed identical. Compare

  v[i+j-1] = v[i+j-1] + 1    -->    v[i+j-1]++
  
  M[i,i+j] = M[i,i+j] * 2    -->    M[i,i+j] *= 2

Remark. Less important but still interesting. The ++, -- and op = operators are slightly more efficient:

  ? a = 106;
  ? i = 0; while(i<a, i=i+1)
  time = 365 ms.
  ? i = 0; while(i<a, i++)
  time = 352 ms.

For the same reason, the shift operators should be preferred to multiplication:

  ? a = 1<<(105);
  ? i = 1; while(i<a, i=i*2);
  time = 1,052 ms.
  ? i = 1; while(i<a, i<<=1);
  time = 617 ms.


\

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.


GP operators

Loosely speaking, an operator is a function, usually attached to basic arithmetic operations, whose name contains only non-alphanumeric characters. For instance + or -, but also = or += , or even [ ] (the selection operator). As all functions, operators take arguments, and return a value; assignment operators also have side effects: besides returning a value, they change the value of some variable.

Each operator has a fixed and unchangeable priority, which means that, in a given expression, the operations with the highest priority is performed first. Unless mentioned otherwise, operators at the same priority level are left-associative (performed from left to right), unless they are assignments, in which case they are right-associative. Anything enclosed between parenthesis is considered a complete subexpression, and is resolved recursively, independently of the surrounding context. For instance,

    a + b + c    -->   (a + b) + c     \\  left-associative
    a = b = c    -->   a = (b = c)     \\  right-associative

Assuming that op1, op2, op3 are binary operators with increasing priorities (think of +, *, ^), x op1 y op2 z op2 x op3 y is equivalent to x op1 ((y op2 z) op2  (x op3 y)).

GP contains many different operators, either unary (having only one argument) or binary, plus a few special selection operators. Unary operators are defined as either prefix or postfix, meaning that they respectively precede (op x) and follow (x op) their single argument. Some symbols are syntactically correct in both positions, like !, but then represent different operators: the ! symbol represents the negation and factorial operators when in prefix and postfix position respectively. Binary operators all use the (infix) syntax x op y.

Most operators are standard (+, %, = ), some are borrowed from the C language (++, << ), and a few are specific to GP (\, #). Beware that some GP operators differ slightly from their C counterparts. For instance, GP's postfix ++ returns the new value, like the prefix ++ of C, and the binary shifts << , >> have a priority which is different from (higher than) that of their C counterparts. When in doubt, just surround everything by parentheses; besides, your code will be more legible.

Here is the list of available operators, ordered by decreasing priority, binary and left-associative unless mentioned otherwise. An expression is an lvalue if something can be assigned to it. (The name comes from left-value, to the left of a = operator; e.g. x, or v[1] are lvalues, but x + 1 is not.)

* Priority 14

: as in x:small, is used to indicate to the GP2C compiler that the variable on the left-hand side always contains objects of the type specified on the right hand-side (here, a small integer) in order to produce more efficient or more readable C code. This is ignored by GP.

* Priority 13 ( ) is the function call operator. If f is a closure and args is a comma-separated list of arguments (possibly empty), f(args) evaluates f on those arguments.

* Priority 12

++ and -- (unary, postfix): if x is an lvalue, x++ assigns the value x+1 to x, then returns the new value of x. This corresponds to the C statement ++x: there is no prefix ++ operator in GP. x-- does the same with x-1. These operators are not associative, i.e. x++++ is invalid, since x++ is not an lvalue.

* Priority 11

.member (unary, postfix): x.member extracts member from structure x (see Section se:member).

[ ] is the selection operator. x[i] returns the i-th component of vector x; x[i,j], x[,j] and x[i,] respectively return the entry of coordinates (i,j), the j-th column, and the i-th row of matrix x. If the assignment operator ( = ) immediately follows a sequence of selections, it assigns its right hand side to the selected component. E.g x[1][1] = 0 is valid; but beware that (x[1])[1] = 0 is not (because the parentheses force the complete evaluation of x[1], and the result is not modifiable).

* Priority 10

' (unary, postfix): derivative with respect to the main variable. If f is a function (tCLOSURE), f' is allowed and defines a new function, which will perform numerical derivation when evaluated at a scalar x; this is defined as (f(x+ϵ) - f(x-ϵ)) / 2ϵ for a suitably small epsilon depending on current precision.

  ? (x2 + y*x + y2)'  \\  derive with respect to main variable x
  %1 = 2*x + y
  ? SIN = cos'
  %2 = cos'
  ? SIN(Pi/6)         \\  numerical derivation
  %3 = -0.5000000000000000000000000000
  ? cos'(Pi/6)        \\  works directly: no need for intermediate SIN
  %4 = -0.5000000000000000000000000000

~ (unary, postfix): vector/matrix transpose.

! (unary, postfix): factorial. x! = x(x-1)...1.

! (unary, prefix): logical not. !x returns 1 if x is equal to 0 (specifically, if gequal0(x) == 1), and 0 otherwise.

* Priority 9

# (unary, prefix): cardinality; #x returns length(x).

* Priority 8

^: powering. This operator is right associative: 234 is understood as 2^(34).

* Priority 7

+, - (unary, prefix): - toggles the sign of its argument, + has no effect whatsoever.

* Priority 6

*: multiplication.

/: exact division (3/2 yields 3/2, not 1.5).

\, %: Euclidean quotient and remainder, i.e. if x = qy + r, then x \ y = q, x%y = r. If x and y are scalars, then q is an integer and r satisfies 0 ≤ r < |y|; if x and y are polynomials, then q and r are polynomials such that deg r < deg y and the leading terms of r and x have the same sign.

\/: rounded Euclidean quotient for integers (rounded towards + oo when the exact quotient would be a half-integer).

<< , >> : left and right binary shift. By definition, x << n  =  x * 2n if n > 0, and truncate(x 2-n) otherwise. Right shift is defined by x >> n  =  x << (-n).

* Priority 5

+, -: addition/subtraction.

* Priority 4

< , > , <= , >= : the usual comparison operators, returning 1 for true and 0 for false. For instance, x <= 1 returns 1 if x ≤ 1 and 0 otherwise.

<> , != : test for (exact) inequality.

== : test for (exact) equality. tQFR having the same coefficients but a different distance component are tested as equal.

=== : test whether two objects are identical component-wise. This is stricter than == : for instance, the integer 0, a 0 polynomial or a vector with 0 entries, are all tested equal by == , but they are not identical.

* Priority 3

&&: logical and.

||: logical (inclusive) or. Any sequence of logical or and and operations is evaluated from left to right, and aborted as soon as the final truth value is known. Thus, for instance,

    x == 0 || test(1/x)

will never produce an error since test(1/x) is not even evaluated when the first test is true (hence the final truth value is true). Similarly

    type(p) == "tINT" && isprime(p)

does not evaluate isprime(p) if p is not an integer.

* Priority 2

= (assignment, lvalue = expr). The result of x  =  y is the value of the expression y, which is also assigned to the variable x. This assignment operator is right-associative. This is not the equality test operator; a statement like x  =  1 is always true (i.e. non-zero), and sets x to 1; the equality test would be x == 1. The right hand side of the assignment operator is evaluated before the left hand side.

It is crucial that the left hand-side be an lvalue there, it avoids ambiguities in expressions like 1 + x = 1. The latter evaluates as 1 + (x = 1), not as (1 + x) = 1, even though the priority of = is lower than the priority of +: 1 + x is not an lvalue.

If the expression cannot be parsed in a way where the left hand side is an lvalue, raise an error.

  ? x + 1 = 1
    ***   syntax error, unexpected '=', expecting $end or ';': x+1=1
    ***                                                           ^--

op = , where op is any binary operator among +, -, *, %, /, \, \/, << , or >> (composed assignment lvalue op = expr). The expression op =  y assigns (x op y) to x, and returns the new value of x. The result is not an lvalue; thus

    (x += 2) = 3

is invalid. These assignment operators are right-associative:

    ? x = 'x; x += x *= 2
    %1 = 3*x

* Priority 1 - > (function definition): (vars)- > expr returns a function object, of type tCLOSURE.

Remark. Use the op = operators as often as possible since they make complex assignments more legible: one needs not parse complicated expressions twice to make sure they are indeed identical. Compare

  v[i+j-1] = v[i+j-1] + 1    -->    v[i+j-1]++
  
  M[i,i+j] = M[i,i+j] * 2    -->    M[i,i+j] *= 2

Remark. Less important but still interesting. The ++, -- and op = operators are slightly more efficient:

  ? a = 106;
  ? i = 0; while(i<a, i=i+1)
  time = 365 ms.
  ? i = 0; while(i<a, i++)
  time = 352 ms.

For the same reason, the shift operators should be preferred to multiplication:

  ? a = 1<<(105);
  ? i = 1; while(i<a, i=i*2);
  time = 1,052 ms.
  ? i = 1; while(i<a, i<<=1);
  time = 617 ms.


^

The expression xn 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 tQFI and tQFR) returns a representative of the class, which is always reduced if the input was. (In particular, x1 returns x itself, whether it is reduced or not.)

PARI is able to rewrite the multiplication x * x of two identical objects as x2, 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 yq = xp 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 tINTMOD 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 tPOLMOD x, the behaviour is the same:

  ? Mod(x2, x3-x)^(-1)
    ***   at top-level: Mod(x2,x3-x)^(-1)
    ***                               ^-----
    *** _^_: impossible inverse in RgXQinv: Mod(x2, x3 - x).

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

  ? a = Mod(3*y3+1, 4); b = y6+y5+y4+y3+y2+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)*y5 + Mod(3,4)*y3 + Mod(1,4)*y2 + Mod(3,4)*y + Mod(2,4)

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

For a tMAT 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 xn.


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 tINTs compare as usual (i.e. cmp(x,y) < 0 if and only if x < y);

* two tVECSMALLs of the same length compare lexicographically;

* two tSTRs 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 cmpuniversal(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 tINTMOD \ tINT.
  ? 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,...,xn] if x0 is omitted, and [x0, x0*x, ..., x0*xn] 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 2n. 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 \ 2n.

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


shiftmul(x, n)

Multiplies x by 2n. 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; tQUAD with positive discriminants and tINFINITY 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, tSTR 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.