Cython usage
The gmpy2 module provides a C-API that can be conveniently used from Cython. All types and functions are declared in the header gmpy2.pxd that is installed automatically in your Python path together with the library.
Initialization
In order to use the C-API you need to make one call to the function void import_gmpy2(void).
Types
The types mpz
, mpq
, mpfr
and mpc
are
declared as extension types in gmpy2.pxd. They correspond respectively to the C
structures MPZ_Object, MPQ_Object, MPFR_Object and MPC_Object.
Fast type checking can be done with the following C functions
- bint MPZ_Check(object)
equivalent to isinstance(obj, mpz)
- bint MPQ_Check(object)
equivalent to isinstance(obj, mpq)
- bint MPFR_Check(object)
equivalent to isinstance(obj, mpfr)
- bint MPC_Check(object)
equivalent to isinstance(obj, mpc)
Object creation
To create a new gmpy2 types there are four basic functions
- mpz GMPy_MPZ_New(void * ctx)
create a new mpz object from a given context ctx
- mpq GMPy_MPQ_New(void * ctx)
create a new mpq object from a given context ctx
- mpfr MPFR_New(void * ctx, mpfr_prec_t prec)
create a new mpfr object with given context ctx and precision prec
- mpc MPC_New(void * ctx, mpfr_prec_t rprec, mpfr_prec_t iprec)
create a new mpc object with given context ctx, precisions rprec and iprec of respectively real and imaginary parts
The context can be set to NULL and controls the default behavior (e.g. precision).
The gmpy2.pxd header also provides convenience macro to wrap a (copy of) a mpz_t, mpq_t, mpfr_t or a mpc_t object into the corresponding gmpy2 type.
- mpz GMPy_MPZ_From_mpz(mpz_srcptr z)
return a new mpz object with a given mpz_t value z
- mpq GMPy_MPQ_From_mpq(mpq_srcptr q)
return a new mpq object from a given mpq_t value q
- mpq GMPy_MPQ_From_mpz(mpz_srcptr num, mpz_srcptr den)
return a new mpq object with a given mpz_t numerator num and mpz_t denominator den
- mpfr GMPy_MPFR_From_mpfr(mpfr_srcptr x)
return a new mpfr object with a given mpfr_t value x
- mpc GMPy_MPC_From_mpc(mpc_srcptr c)
return a new mpc object with a given mpc_t value c
- mpc GMPy_MPC_From_mpfr(mpfr_srcptr re, mpfr_srcptr im)
return a new mpc object with a given mpfr_t real part re and mpfr_t imaginary part im
Access to the underlying C type
Each of the gmpy2 objects has a field corresponding to the underlying C type. The following functions give access to this field
mpz_t MPZ(mpz)
mpq_t MPQ(mpq)
mpfr_t MPFR(mpfr)
mpc_t MPC(mpc)
Compilation
The header gmpy2.pxd as well as the C header gmpy2.h from which it depends are installed in the Python path. In order to make Cython and the C compiler aware of the existence of these files, the Python path should be part of the include directories.
Recall that import_gmpy2() needs to be called before any other function of the C-API.
Here is a minimal example of a Cython file test_gmpy2.pyx:
"A minimal cython file test_gmpy2.pyx"
from gmpy2 cimport *
cdef extern from "gmp.h":
void mpz_set_si(mpz_t, long)
import_gmpy2() # needed to initialize the C-API
cdef mpz z = GMPy_MPZ_New(NULL)
mpz_set_si(MPZ(z), -7)
print(z + 3)
The corresponding setup.py is given below.
"A minimal setup.py for compiling test_gmpy2.pyx"
import sys
from setuptools import Extension, setup
from Cython.Build import cythonize
ext = Extension("test_gmpy2", ["test_gmpy2.pyx"],
include_dirs=sys.path, libraries=['gmp', 'mpfr', 'mpc'])
setup(name="cython_gmpy_test",
ext_modules=cythonize([ext], include_path=sys.path))
With these two files in the same repository, you should be able to compile your module using
$ python setup.py build_ext --inplace
For more about compilation and installation of cython files and extension modules, please refer to the official documentation of Cython and distutils.