# 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.