Convert PARI objects to Sage types - C/C++ Library Interfaces

Skip to content
Back to top
View this page
Edit this page

# Convert PARI objects to Sage types

sage.libs.pari.convert_sage.gen_to_sage(z, locals=None)

  Convert a PARI gen to a Sage/Python object.

  INPUT:

  - `z` – PARI `gen`

  - `locals` – (optional) dictionary used in fallback cases that involve `sage_eval()`

  OUTPUT: one of the following depending on the PARI type of `z`

  - a `Integer` if `z` is an integer (type `t_INT`)

  - a `Rational` if `z` is a rational (type `t_FRAC`)

  - a `RealNumber` if `z` is a real number (type `t_REAL`). The precision will be equivalent.

  - a `NumberFieldElement_quadratic` or a `ComplexNumber` if `z` is a complex number (type `t_COMPLEX`). The former is used when the real and imaginary parts are integers or rationals and the latter when they are floating point numbers. In that case The precision will be the maximal precision of the real and imaginary parts.

  - a Python list if `z` is a vector or a list (type `t_VEC`, `t_COL`)

  - a Python string if `z` is a string (type `t_STR`)

  - a Python list of Python integers if `z` is a small vector (type `t_VECSMALL`)

  - a matrix if `z` is a matrix (type `t_MAT`)

  - a \(p\)-adic element (type `t_PADIC`)

  - a `Infinity` if `z` is an infinity (type `t_INF`)

  EXAMPLES:

  Sage

      sage: from sage.libs.pari.convert_sage import gen_to_sage

  Python

      >>> from sage.all import *
      >>> from sage.libs.pari.convert_sage import gen_to_sage

  Converting an integer:

  Sage

      sage: z = pari('12'); z
      12
      sage: z.type()
      't_INT'
      sage: a = gen_to_sage(z); a
      12
      sage: a.parent()
      Integer Ring

      sage: gen_to_sage(pari('7^42'))
      311973482284542371301330321821976049

  [Python]

      >>> from sage.all import *
      >>> z = pari('12'); z
      12
      >>> z.type()
      't_INT'
      >>> a = gen_to_sage(z); a
      12
      >>> a.parent()
      Integer Ring

      >>> gen_to_sage(pari('7^42'))
      311973482284542371301330321821976049

  Converting a rational number:

  Sage

      sage: z = pari('389/17'); z
      389/17
      sage: z.type()
      't_FRAC'
      sage: a = gen_to_sage(z); a
      389/17
      sage: a.parent()
      Rational Field

      sage: gen_to_sage(pari('5^30 / 3^50'))
      931322574615478515625/717897987691852588770249

  Python

      >>> from sage.all import *
      >>> z = pari('389/17'); z
      389/17
      >>> z.type()
      't_FRAC'
      >>> a = gen_to_sage(z); a
      389/17
      >>> a.parent()
      Rational Field

      >>> gen_to_sage(pari('5^30 / 3^50'))
      931322574615478515625/717897987691852588770249

  Converting a real number:

  Sage

      sage: pari.set_real_precision(70)
      15
      sage: z = pari('1.234'); z
      1.234000000000000000000000000000000000000000000000000000000000000000000
      sage: a = gen_to_sage(z); a                                                     # needs sage.rings.real_mpfr
      1.234000000000000000000000000000000000000000000000000000000000000000000000000
      sage: a.parent()                                                                # needs sage.rings.real_mpfr
      Real Field with 256 bits of precision
      sage: pari.set_real_precision(15)
      70
      sage: a = gen_to_sage(pari('1.234')); a                                         # needs sage.rings.real_mpfr
      1.23400000000000000
      sage: a.parent()                                                                # needs sage.rings.real_mpfr
      Real Field with 64 bits of precision

  [Python]

      >>> from sage.all import *
      >>> pari.set_real_precision(Integer(70))
      15
      >>> z = pari('1.234'); z
      1.234000000000000000000000000000000000000000000000000000000000000000000
      >>> a = gen_to_sage(z); a                                                     # needs sage.rings.real_mpfr
      1.234000000000000000000000000000000000000000000000000000000000000000000000000
      >>> a.parent()                                                                # needs sage.rings.real_mpfr
      Real Field with 256 bits of precision
      >>> pari.set_real_precision(Integer(15))
      70
      >>> a = gen_to_sage(pari('1.234')); a                                         # needs sage.rings.real_mpfr
      1.23400000000000000
      >>> a.parent()                                                                # needs sage.rings.real_mpfr
      Real Field with 64 bits of precision

  For complex numbers, the parent depends on the PARI type:

  Sage

      sage: z = pari('(3+I)'); z
      3 + I
      sage: z.type()
      't_COMPLEX'
      sage: a = gen_to_sage(z); a                                                     # needs sage.rings.number_field
      i + 3
      sage: a.parent()                                                                # needs sage.rings.number_field
      Number Field in i with defining polynomial x^2 + 1 with i = 1*I

      sage: z = pari('(3+I)/2'); z
      3/2 + 1/2*I
      sage: a = gen_to_sage(z); a                                                     # needs sage.rings.number_field
      1/2*i + 3/2
      sage: a.parent()                                                                # needs sage.rings.number_field
      Number Field in i with defining polynomial x^2 + 1 with i = 1*I

      sage: z = pari('1.0 + 2.0*I'); z
      1.00000000000000 + 2.00000000000000*I
      sage: a = gen_to_sage(z); a                                                     # needs sage.rings.real_mpfr
      1.00000000000000000 + 2.00000000000000000*I
      sage: a.parent()                                                                # needs sage.rings.real_mpfr
      Complex Field with 64 bits of precision

      sage: z = pari('1 + 1.0*I'); z
      1 + 1.00000000000000*I
      sage: a = gen_to_sage(z); a                                                     # needs sage.rings.real_mpfr
      1.00000000000000000 + 1.00000000000000000*I
      sage: a.parent()                                                                # needs sage.rings.real_mpfr
      Complex Field with 64 bits of precision

      sage: z = pari('1.0 + 1*I'); z
      1.00000000000000 + I
      sage: a = gen_to_sage(z); a                                                     # needs sage.rings.real_mpfr
      1.00000000000000000 + 1.00000000000000000*I
      sage: a.parent()                                                                # needs sage.rings.real_mpfr
      Complex Field with 64 bits of precision

  Python

      >>> from sage.all import *
      >>> z = pari('(3+I)'); z
      3 + I
      >>> z.type()
      't_COMPLEX'
      >>> a = gen_to_sage(z); a                                                     # needs sage.rings.number_field
      i + 3
      >>> a.parent()                                                                # needs sage.rings.number_field
      Number Field in i with defining polynomial x^2 + 1 with i = 1*I

      >>> z = pari('(3+I)/2'); z
      3/2 + 1/2*I
      >>> a = gen_to_sage(z); a                                                     # needs sage.rings.number_field
      1/2*i + 3/2
      >>> a.parent()                                                                # needs sage.rings.number_field
      Number Field in i with defining polynomial x^2 + 1 with i = 1*I

      >>> z = pari('1.0 + 2.0*I'); z
      1.00000000000000 + 2.00000000000000*I
      >>> a = gen_to_sage(z); a                                                     # needs sage.rings.real_mpfr
      1.00000000000000000 + 2.00000000000000000*I
      >>> a.parent()                                                                # needs sage.rings.real_mpfr
      Complex Field with 64 bits of precision

      >>> z = pari('1 + 1.0*I'); z
      1 + 1.00000000000000*I
      >>> a = gen_to_sage(z); a                                                     # needs sage.rings.real_mpfr
      1.00000000000000000 + 1.00000000000000000*I
      >>> a.parent()                                                                # needs sage.rings.real_mpfr
      Complex Field with 64 bits of precision

      >>> z = pari('1.0 + 1*I'); z
      1.00000000000000 + I
      >>> a = gen_to_sage(z); a                                                     # needs sage.rings.real_mpfr
      1.00000000000000000 + 1.00000000000000000*I
      >>> a.parent()                                                                # needs sage.rings.real_mpfr
      Complex Field with 64 bits of precision

  Converting polynomials:

  Sage

      sage: f = pari('(2/3)*x^3 + x - 5/7 + y')
      sage: f.type()
      't_POL'

      sage: R.<x,y> = QQ[]
      sage: gen_to_sage(f, {'x': x, 'y': y})
      2/3*x^3 + x + y - 5/7
      sage: parent(gen_to_sage(f, {'x': x, 'y': y}))
      Multivariate Polynomial Ring in x, y over Rational Field

      sage: # needs sage.symbolic
      sage: x,y = SR.var('x,y')
      sage: gen_to_sage(f, {'x': x, 'y': y})
      2/3*x^3 + x + y - 5/7
      sage: parent(gen_to_sage(f, {'x': x, 'y': y}))
      Symbolic Ring

      sage: gen_to_sage(f)
      Traceback (most recent call last):
      ...
      NameError: name 'x' is not defined

  [Python]

      >>> from sage.all import *
      >>> f = pari('(2/3)*x^3 + x - 5/7 + y')
      >>> f.type()
      't_POL'

      >>> R = QQ['x, y']; (x, y,) = R._first_ngens(2)
      >>> gen_to_sage(f, {'x': x, 'y': y})
      2/3*x^3 + x + y - 5/7
      >>> parent(gen_to_sage(f, {'x': x, 'y': y}))
      Multivariate Polynomial Ring in x, y over Rational Field

      >>> # needs sage.symbolic
      >>> x,y = SR.var('x,y')
      >>> gen_to_sage(f, {'x': x, 'y': y})
      2/3*x^3 + x + y - 5/7
      >>> parent(gen_to_sage(f, {'x': x, 'y': y}))
      Symbolic Ring

      >>> gen_to_sage(f)
      Traceback (most recent call last):
      ...
      NameError: name 'x' is not defined

  Converting vectors:

  Sage

      sage: # needs sage.rings.number_field sage.rings.real_mpfr
      sage: z1 = pari('[-3, 2.1, 1+I]'); z1
      [-3, 2.10000000000000, 1 + I]
      sage: z2 = pari('[1.0*I, [1,2]]~'); z2
      [1.00000000000000*I, [1, 2]]~
      sage: z1.type(), z2.type()
      ('t_VEC', 't_COL')
      sage: a1 = gen_to_sage(z1)
      sage: a2 = gen_to_sage(z2)
      sage: type(a1), type(a2)
      (<... 'list'>, <... 'list'>)
      sage: [parent(b) for b in a1]
      [Integer Ring,
       Real Field with 64 bits of precision,
       Number Field in i with defining polynomial x^2 + 1 with i = 1*I]
      sage: [parent(b) for b in a2]
      [Complex Field with 64 bits of precision, <... 'list'>]

      sage: z = pari('Vecsmall([1,2,3,4])')
      sage: z.type()
      't_VECSMALL'
      sage: a = gen_to_sage(z); a
      [1, 2, 3, 4]
      sage: type(a)
      <... 'list'>
      sage: [parent(b) for b in a]
      [<... 'int'>, <... 'int'>, <... 'int'>, <... 'int'>]

  Python

      >>> from sage.all import *
      >>> # needs sage.rings.number_field sage.rings.real_mpfr
      >>> z1 = pari('[-3, 2.1, 1+I]'); z1
      [-3, 2.10000000000000, 1 + I]
      >>> z2 = pari('[1.0*I, [1,2]]~'); z2
      [1.00000000000000*I, [1, 2]]~
      >>> z1.type(), z2.type()
      ('t_VEC', 't_COL')
      >>> a1 = gen_to_sage(z1)
      >>> a2 = gen_to_sage(z2)
      >>> type(a1), type(a2)
      (<... 'list'>, <... 'list'>)
      >>> [parent(b) for b in a1]
      [Integer Ring,
       Real Field with 64 bits of precision,
       Number Field in i with defining polynomial x^2 + 1 with i = 1*I]
      >>> [parent(b) for b in a2]
      [Complex Field with 64 bits of precision, <... 'list'>]

      >>> z = pari('Vecsmall([1,2,3,4])')
      >>> z.type()
      't_VECSMALL'
      >>> a = gen_to_sage(z); a
      [1, 2, 3, 4]
      >>> type(a)
      <... 'list'>
      >>> [parent(b) for b in a]
      [<... 'int'>, <... 'int'>, <... 'int'>, <... 'int'>]

  Matrices:

  Sage

      sage: z = pari('[1,2;3,4]')
      sage: z.type()
      't_MAT'

      sage: # needs sage.modules
      sage: a = gen_to_sage(z); a
      [1 2]
      [3 4]
      sage: a.parent()
      Full MatrixSpace of 2 by 2 dense matrices over Integer Ring

  [Python]

      >>> from sage.all import *
      >>> z = pari('[1,2;3,4]')
      >>> z.type()
      't_MAT'

      >>> # needs sage.modules
      >>> a = gen_to_sage(z); a
      [1 2]
      [3 4]
      >>> a.parent()
      Full MatrixSpace of 2 by 2 dense matrices over Integer Ring

  Conversion of \(p\)-adics:

  Sage

      sage: # needs sage.rings.padics
      sage: z = pari('569 + O(7^8)'); z
      2 + 4*7 + 4*7^2 + 7^3 + O(7^8)
      sage: a = gen_to_sage(z); a
      2 + 4*7 + 4*7^2 + 7^3 + O(7^8)
      sage: a.parent()
      7-adic Field with capped relative precision 8

  Python

      >>> from sage.all import *
      >>> # needs sage.rings.padics
      >>> z = pari('569 + O(7^8)'); z
      2 + 4*7 + 4*7^2 + 7^3 + O(7^8)
      >>> a = gen_to_sage(z); a
      2 + 4*7 + 4*7^2 + 7^3 + O(7^8)
      >>> a.parent()
      7-adic Field with capped relative precision 8

  Conversion of infinities:

  Sage

      sage: gen_to_sage(pari('oo'))
      +Infinity
      sage: gen_to_sage(pari('-oo'))
      -Infinity

  [Python]

      >>> from sage.all import *
      >>> gen_to_sage(pari('oo'))
      +Infinity
      >>> gen_to_sage(pari('-oo'))
      -Infinity

  Conversion of strings:

  Sage

      sage: s = pari('"foo"').sage(); s
      'foo'
      sage: type(s)
      <class 'str'>

  Python

      >>> from sage.all import *
      >>> s = pari('"foo"').sage(); s
      'foo'
      >>> type(s)
      <class 'str'>

sage.libs.pari.convert_sage.new_gen_from_integer(self)

sage.libs.pari.convert_sage.new_gen_from_rational(self)

sage.libs.pari.convert_sage.pari_divisors_small(self)

  Return the list of divisors of this number using PARI `divisorsu`.

  See also

  This method is better used through `sage.rings.integer.Integer.divisors()`.

  EXAMPLES:

  Sage

      sage: from sage.libs.pari.convert_sage import pari_divisors_small
      sage: pari_divisors_small(4)
      [1, 2, 4]

  Python

      >>> from sage.all import *
      >>> from sage.libs.pari.convert_sage import pari_divisors_small
      >>> pari_divisors_small(Integer(4))
      [1, 2, 4]

  The integer must fit into an unsigned long:

  Sage

      sage: pari_divisors_small(-4)
      Traceback (most recent call last):
      ...
      AssertionError
      sage: pari_divisors_small(2**65)
      Traceback (most recent call last):
      ...
      AssertionError

  [Python]

      >>> from sage.all import *
      >>> pari_divisors_small(-Integer(4))
      Traceback (most recent call last):
      ...
      AssertionError
      >>> pari_divisors_small(Integer(2)**Integer(65))
      Traceback (most recent call last):
      ...
      AssertionError

sage.libs.pari.convert_sage.pari_is_prime(p)

  Return whether `p` is a prime.

  The caller must ensure that `p.value` fits in a long.

  EXAMPLES:

  Sage

      sage: from sage.libs.pari.convert_sage import pari_is_prime
      sage: pari_is_prime(2)
      True
      sage: pari_is_prime(3)
      True
      sage: pari_is_prime(1)
      False
      sage: pari_is_prime(4)
      False

  Python

      >>> from sage.all import *
      >>> from sage.libs.pari.convert_sage import pari_is_prime
      >>> pari_is_prime(Integer(2))
      True
      >>> pari_is_prime(Integer(3))
      True
      >>> pari_is_prime(Integer(1))
      False
      >>> pari_is_prime(Integer(4))
      False

  Its recommended to use `sage.rings.integer.Integer.is_prime()`, which checks overflow. The following is incorrect, because the number does not fit into a long:

  Sage

      sage: pari_is_prime(2**64 + 2)
      True

  [Python]

      >>> from sage.all import *
      >>> pari_is_prime(Integer(2)**Integer(64) + Integer(2))
      True

sage.libs.pari.convert_sage.pari_is_prime_power(q, get_data)

  Return whether `q` is a prime power.

  The caller must ensure that `q.value` fits in a long.

  OUTPUT:

  If `get_data` return a tuple of the prime and the exponent. Otherwise return a boolean.

  EXAMPLES:

  Sage

      sage: from sage.libs.pari.convert_sage import pari_is_prime_power
      sage: pari_is_prime_power(2, False)
      True
      sage: pari_is_prime_power(2, True)
      (2, 1)
      sage: pari_is_prime_power(4, False)
      True
      sage: pari_is_prime_power(4, True)
      (2, 2)
      sage: pari_is_prime_power(6, False)
      False
      sage: pari_is_prime_power(6, True)
      (6, 0)

  Python

      >>> from sage.all import *
      >>> from sage.libs.pari.convert_sage import pari_is_prime_power
      >>> pari_is_prime_power(Integer(2), False)
      True
      >>> pari_is_prime_power(Integer(2), True)
      (2, 1)
      >>> pari_is_prime_power(Integer(4), False)
      True
      >>> pari_is_prime_power(Integer(4), True)
      (2, 2)
      >>> pari_is_prime_power(Integer(6), False)
      False
      >>> pari_is_prime_power(Integer(6), True)
      (6, 0)

  Its recommended to use `sage.rings.integer.Integer.is_prime_power()`, which checks overflow. The following is incorrect, because the number does not fit into a long:

  Sage

      sage: pari_is_prime_power(2**64 + 2, False)
      True

  [Python]

      >>> from sage.all import *
      >>> pari_is_prime_power(Integer(2)**Integer(64) + Integer(2), False)
      True

sage.libs.pari.convert_sage.pari_maxprime()

  Return to which limit PARI has computed the primes.

  EXAMPLES:

  Sage

      sage: from sage.libs.pari.convert_sage import pari_maxprime
      sage: a = pari_maxprime()
      sage: res = prime_range(2, 2*a)
      sage: b = pari_maxprime()
      sage: b >= 2*a
      True

  Python

      >>> from sage.all import *
      >>> from sage.libs.pari.convert_sage import pari_maxprime
      >>> a = pari_maxprime()
      >>> res = prime_range(Integer(2), Integer(2)*a)
      >>> b = pari_maxprime()
      >>> b >= Integer(2)*a
      True

sage.libs.pari.convert_sage.pari_prime_range(c_start, c_stop, py_ints=False)

  Return a list of all primes between `start` and `stop - 1`, inclusive.

  See also

  `sage.rings.fast_arith.prime_range()`

sage.libs.pari.convert_sage.set_integer_from_gen(self, x)

  EXAMPLES:

  Sage

      sage: [Integer(pari(x)) for x in [1, 2^60, 2., GF(3)(1), GF(9,'a')(2)]]         # needs sage.rings.finite_rings
      [1, 1152921504606846976, 2, 1, 2]
      sage: Integer(pari(2.1)) # indirect doctest
      Traceback (most recent call last):
      ...
      TypeError: Attempt to coerce non-integral real number to an Integer

  Python

      >>> from sage.all import *
      >>> [Integer(pari(x)) for x in [Integer(1), Integer(2)**Integer(60), RealNumber('2.'), GF(Integer(3))(Integer(1)), GF(Integer(9),'a')(Integer(2))]]         # needs sage.rings.finite_rings
      [1, 1152921504606846976, 2, 1, 2]
      >>> Integer(pari(RealNumber('2.1'))) # indirect doctest
      Traceback (most recent call last):
      ...
      TypeError: Attempt to coerce non-integral real number to an Integer

sage.libs.pari.convert_sage.set_rational_from_gen(self, x)

  EXAMPLES:

  Sage

      sage: [Rational(pari(x)) for x in [1, 1/2, 2^60, 2., GF(3)(1), GF(9,'a')(2)]]   # needs sage.rings.finite_rings
      [1, 1/2, 1152921504606846976, 2, 1, 2]
      sage: Rational(pari(2.1)) # indirect doctest
      Traceback (most recent call last):
      ...
      TypeError: Attempt to coerce non-integral real number to an Integer

  Python

      >>> from sage.all import *
      >>> [Rational(pari(x)) for x in [Integer(1), Integer(1)/Integer(2), Integer(2)**Integer(60), RealNumber('2.'), GF(Integer(3))(Integer(1)), GF(Integer(9),'a')(Integer(2))]]   # needs sage.rings.finite_rings
      [1, 1/2, 1152921504606846976, 2, 1, 2]
      >>> Rational(pari(RealNumber('2.1'))) # indirect doctest
      Traceback (most recent call last):
      ...
      TypeError: Attempt to coerce non-integral real number to an Integer