diff --git a/docs/advmpz.rst b/docs/advmpz.rst index 35868232..63cf4390 100644 --- a/docs/advmpz.rst +++ b/docs/advmpz.rst @@ -1,11 +1,8 @@ -Multiple-precision Integers (Advanced topics) -============================================= +Integers (Advanced topics) +========================== .. currentmodule:: gmpy2 -The xmpz type -------------- - gmpy2 provides access to an experimental integer type called `xmpz`. The `xmpz` type is a mutable integer type. In-place operations (+=, //=, etc.) modify the original object and do not create a new object. Instances of @@ -124,6 +121,9 @@ prime numbers. print(len(result)) +The xmpz type +------------- + .. autoclass:: xmpz :special-members: __format__ diff --git a/docs/contexts.rst b/docs/contexts.rst index 9cf927d3..504c8935 100644 --- a/docs/contexts.rst +++ b/docs/contexts.rst @@ -1,14 +1,10 @@ +.. _contexts: + Contexts ======== .. currentmodule:: gmpy2 -A `context` type is used to control the behavior -of `mpfr` and `mpc` arithmetic. In addition to controlling the -precision, the rounding mode can be specified, minimum and maximum exponent -values can be changed, various exceptions can be raised or ignored, gradual -underflow can be enabled, and returning complex results can be enabled. - `context()` creates a new context with all options set to default. `set_context()` will set the active context. `get_context()` will return a reference to the active context. Note that contexts are mutable: @@ -16,51 +12,6 @@ modifying the reference returned by `get_context()` will modify the active context until a new context is enabled with `set_context()`. The `~context.copy()` method of a context will return a copy of the context. -The following example just modifies the precision. The remaining options will -be discussed later. - -.. doctest:: - - >>> import gmpy2 - >>> from gmpy2 import mpfr - >>> gmpy2.set_context(gmpy2.context()) - >>> gmpy2.get_context() - context(precision=53, real_prec=Default, imag_prec=Default, - round=RoundToNearest, real_round=Default, imag_round=Default, - emax=1073741823, emin=-1073741823, - subnormalize=False, - trap_underflow=False, underflow=False, - trap_overflow=False, overflow=False, - trap_inexact=False, inexact=False, - trap_invalid=False, invalid=False, - trap_erange=False, erange=False, - trap_divzero=False, divzero=False, - allow_complex=False, - rational_division=False, - allow_release_gil=False) - >>> gmpy2.sqrt(5) - mpfr('2.2360679774997898') - >>> gmpy2.get_context().precision=100 - >>> gmpy2.sqrt(5) - mpfr('2.2360679774997896964091736687316',100) - >>> gmpy2.get_context().precision+=20 - >>> gmpy2.sqrt(5) - mpfr('2.2360679774997896964091736687312762351',120) - >>> ctx=gmpy2.get_context() - >>> ctx.precision+=20 - >>> gmpy2.sqrt(5) - mpfr('2.2360679774997896964091736687312762354406182',140) - >>> gmpy2.set_context(gmpy2.context()) - >>> gmpy2.sqrt(5) - mpfr('2.2360679774997898') - >>> ctx.precision+=20 - >>> gmpy2.sqrt(5) - mpfr('2.2360679774997898') - >>> gmpy2.set_context(ctx) - >>> gmpy2.sqrt(5) - mpfr('2.2360679774997896964091736687312762354406183596116',160) - >>> gmpy2.set_context(gmpy2.context()) - Context Type ------------ @@ -93,6 +44,7 @@ set to 100. When the block is finished, the original context is restored. .. doctest:: + >>> import gmpy2 >>> print(gmpy2.sqrt(2)) 1.4142135623730951 >>> with gmpy2.local_context(gmpy2.context(), precision=100) as ctx: diff --git a/docs/exceptions.rst b/docs/exceptions.rst new file mode 100644 index 00000000..8cf9d1a1 --- /dev/null +++ b/docs/exceptions.rst @@ -0,0 +1,11 @@ +Exceptions +---------- + +.. currentmodule:: gmpy2 + +.. autoexception:: RangeError +.. autoexception:: InexactResultError +.. autoexception:: OverflowResultError +.. autoexception:: UnderflowResultError +.. autoexception:: InvalidOperationError +.. autoexception:: DivisionByZeroError diff --git a/docs/generic.rst b/docs/generic.rst new file mode 100644 index 00000000..2036c5ec --- /dev/null +++ b/docs/generic.rst @@ -0,0 +1,18 @@ +Generic Functions +----------------- + +.. currentmodule:: gmpy2 + +.. autofunction:: add +.. autofunction:: div +.. autofunction:: mul +.. autofunction:: sub + +.. autofunction:: square + +.. autofunction:: f2q + +.. autofunction:: fma +.. autofunction:: fms + +.. autofunction:: cmp_abs diff --git a/docs/index.rst b/docs/index.rst index 697336ab..6dcae0e3 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -24,14 +24,18 @@ Contents .. toctree:: :maxdepth: 2 - install overview + install + tutorial mpz advmpz mpq contexts + exceptions mpfr mpc + generic + misc cython conversion history diff --git a/docs/misc.rst b/docs/misc.rst new file mode 100644 index 00000000..01e6fd30 --- /dev/null +++ b/docs/misc.rst @@ -0,0 +1,17 @@ +Miscellaneous Functions +----------------------- + +.. currentmodule:: gmpy2 + +.. autofunction:: digits +.. autofunction:: from_binary +.. autofunction:: license +.. autofunction:: mp_limbsize +.. autofunction:: mp_version +.. autofunction:: mpc_version +.. autofunction:: mpfr_version +.. autofunction:: random_state +.. autofunction:: to_binary +.. autofunction:: version + + diff --git a/docs/mpc.rst b/docs/mpc.rst index 255af73f..20b787c9 100644 --- a/docs/mpc.rst +++ b/docs/mpc.rst @@ -3,72 +3,6 @@ Multiple-precision Complex .. currentmodule:: gmpy2 -gmpy2 adds a multiple-precision complex type called `mpc` that is based -on the MPC library. The context manager settings for `mpfr` arithmetic are -applied to `mpc` arithmetic by default. It is possible to specify -different precision and rounding modes for both the real and imaginary -components of an `mpc`. - -.. doctest:: - - >>> import gmpy2 - >>> from gmpy2 import mpc - >>> gmpy2.set_context(gmpy2.context()) - >>> gmpy2.sqrt(mpc("1+2j")) - mpc('1.272019649514069+0.78615137775742328j') - >>> gmpy2.set_context(gmpy2.context(real_prec=60,imag_prec=70)) - >>> gmpy2.get_context() - context(precision=53, real_prec=60, imag_prec=70, - round=RoundToNearest, real_round=Default, imag_round=Default, - emax=1073741823, emin=-1073741823, - subnormalize=False, - trap_underflow=False, underflow=False, - trap_overflow=False, overflow=False, - trap_inexact=False, inexact=False, - trap_invalid=False, invalid=False, - trap_erange=False, erange=False, - trap_divzero=False, divzero=False, - allow_complex=False, - rational_division=False, - allow_release_gil=False) - >>> gmpy2.sqrt(mpc("1+2j")) - mpc('1.272019649514068965+0.78615137775742328606947j',(60,70)) - >>> gmpy2.set_context(gmpy2.context()) - -Exceptions are normally raised in Python when the result of a real operation -is not defined over the reals; for example, ``sqrt(-4)`` will raise an -exception. The default context in gmpy2 implements the same behavior but by -setting allow_complex to True, complex results will be returned. - -.. doctest:: - - >>> import gmpy2 - >>> from gmpy2 import mpc - >>> gmpy2.sqrt(-4) - mpfr('nan') - >>> gmpy2.get_context().allow_complex=True - >>> gmpy2.sqrt(-4) - mpc('0.0+2.0j') - -The `mpc` type supports the `~mpc.__format__()` special method to -allow custom output formatting. - -.. doctest:: - - >>> import gmpy2 - >>> from gmpy2 import mpc - >>> a=gmpy2.sqrt(mpc("1+2j")) - >>> a - mpc('1.272019649514069+0.78615137775742328j') - >>> "{0:.4.4Mf}".format(a) - '(1.2720 0.7862)' - >>> "{0:.4.4f}".format(a) - '1.2720+0.7862j' - >>> "{0:^20.4.4U}".format(a) - ' 1.2721+0.7862j ' - >>> "{0:^20.4.4D}".format(a) - ' 1.2720+0.7861j ' - mpc Type -------- diff --git a/docs/mpfr.rst b/docs/mpfr.rst index fcbd0152..5dcaa4a3 100644 --- a/docs/mpfr.rst +++ b/docs/mpfr.rst @@ -3,49 +3,6 @@ Multiple-precision Reals .. currentmodule:: gmpy2 -The `mpfr` type is based on the MPFR library. The new `mpfr` type supports -correct rounding, selectable rounding modes, and many trigonometric, -exponential, and special functions. A *context manager* is used to control -precision, rounding modes, and the behavior of exceptions. - -The default precision of an `mpfr` is 53 bits - the same precision as Python's -`float` type. If the precision is changed, then ``mpfr(float('1.2'))`` differs -from ``mpfr('1.2')``. To take advantage of the higher precision provided by -the `mpfr` type, always pass constants as strings. - -.. doctest:: - - >>> import gmpy2 - >>> from gmpy2 import mpfr - >>> gmpy2.set_context(gmpy2.context()) - >>> mpfr('1.2') - mpfr('1.2') - >>> mpfr(float('1.2')) - mpfr('1.2') - >>> gmpy2.get_context().precision=100 - >>> mpfr('1.2') - mpfr('1.2000000000000000000000000000006',100) - >>> mpfr(float('1.2')) - mpfr('1.1999999999999999555910790149937',100) - -The `mpfr` type supports the `~mpfr.__format__()` special method to -allow custom output formatting. - -.. doctest:: - - >>> from gmpy2 import mpfr - >>> a=mpfr("1.23456") - >>> "{0:15.3f}".format(a) - ' 1.235' - >>> "{0:15.3Uf}".format(a) - ' 1.235' - >>> "{0:15.3Df}".format(a) - ' 1.234' - >>> "{0:.3Df}".format(a) - '1.234' - >>> "{0:+.3Df}".format(a) - '+1.234' - mpfr Type --------- diff --git a/docs/mpq.rst b/docs/mpq.rst index 6ece66c1..ca17ed10 100644 --- a/docs/mpq.rst +++ b/docs/mpq.rst @@ -1,21 +1,8 @@ -Multiple-precision Rationals -============================ +Rationals +========= .. currentmodule:: gmpy2 -gmpy2 provides a rational type `mpq`. It should be a replacement for -Python's `~fractions.Fraction` class. - -.. doctest:: - - >>> from gmpy2 import mpq - >>> mpq(1,7) - mpq(1,7) - >>> mpq(1,7) * 11 - mpq(11,7) - >>> mpq(11,7)/13 - mpq(11,91) - mpq type -------- diff --git a/docs/mpz.rst b/docs/mpz.rst index 60430a7f..ae01ace2 100644 --- a/docs/mpz.rst +++ b/docs/mpz.rst @@ -1,38 +1,8 @@ -Multiple-precision Integers -=========================== +Integers +======== .. currentmodule:: gmpy2 -The gmpy2 `mpz` type supports arbitrary precision integers. It should be a -drop-in replacement for Python's `int` type. Depending on the platform and the -specific operation, an `mpz` will be faster than Python's `int` once the -precision exceeds 20 to 50 digits. All the special integer functions in GMP are -supported. - -Examples --------- - -.. doctest:: - - >>> from gmpy2 import is_prime, mpz - >>> mpz('123') + 1 - mpz(124) - >>> 10 - mpz(1) - mpz(9) - >>> is_prime(17) - True - >>> mpz('1_2') - mpz(12) - -.. note:: - The use of ``from gmpy2 import *`` is not recommended. The names in gmpy2 - have been chosen to avoid conflict with Python's builtin names but gmpy2 - does use names that may conflict with other modules or variable names. - -.. note:: - `mpz` ignores all embedded underscore characters. It does not attempt to be - 100% compatible with all Python exceptions. - mpz type -------- diff --git a/docs/overview.rst b/docs/overview.rst index 8c31be20..5878a2a4 100644 --- a/docs/overview.rst +++ b/docs/overview.rst @@ -3,158 +3,19 @@ Overview .. currentmodule:: gmpy2 -Tutorial --------- - -The `mpz` type is compatible with Python's built-in `int` type but is -significantly faster for large values. The cutover point for performance -varies, but can be as low as 20 to 40 digits. A variety of additional integer -functions are provided. - -Operator overloading is fully supported. Coversion from native Python types is +The `mpz` and `mpq` types support arbitrary precision integers and rationals +via the GMP library. These types should be drop-in replacements for Python's +`int`'s and `~fractions.Fraction`'s, but are significantly faster for large +values. The cutover point for performance varies, but can be as low as 20 to +40 digits. All the special integer functions in the GMP are supported. + +The `mpfr` and `mpc` types provide support for correctly rounded multiple +precision real and complex arithmetic via the MPFR and MPC libraries. The +`context` type is used to control precision, rounding modes, and exceptional +conditions. For example, division by zero can either return an Infinity or +raise an exception. It is possible to specify different precision and rounding +modes for both the real and imaginary components of an `mpc`. The default +precision is 53 bits --- just same as for Python's `float` and `complex` types. + +Operator overloading is fully supported. Coversion from native Python types is optimized for performance. - -.. doctest:: - - >>> import gmpy2 - >>> from gmpy2 import mpz,mpq,mpfr,mpc - >>> gmpy2.set_context(gmpy2.context()) - >>> mpz(99) * 43 - mpz(4257) - >>> pow(mpz(99), 37, 59) - mpz(18) - >>> gmpy2.isqrt(99) - mpz(9) - >>> gmpy2.isqrt_rem(99) - (mpz(9), mpz(18)) - >>> gmpy2.gcd(123,27) - mpz(3) - >>> gmpy2.lcm(123,27) - mpz(1107) - >>> (mpz(123) + 12) / 5 - mpfr('27.0') - >>> (mpz(123) + 12) // 5 - mpz(27) - >>> (mpz(123) + 12) / 5.0 - mpfr('27.0') - -The `mpq` type is compatible with the `~fractions.Fraction` type included with -Python. - -.. doctest:: - - >>> mpq(3,7)/7 - mpq(3,49) - >>> mpq(45,3) * mpq(11,8) - mpq(165,8) - -gmpy2 supports correctly rounded arbitrary precision real and complex arithmetic -via the MPFR and MPC libraries. Floating point contexts are used to control precision, -rounding modes, and exceptional conditions. For example, division by zero can either -return an Infinity or raise an exception. - -.. doctest:: - - >>> gmpy2.set_context(gmpy2.context()) - >>> mpfr(1)/7 - mpfr('0.14285714285714285') - >>> gmpy2.get_context().precision=200 - >>> mpfr(1)/7 - mpfr('0.1428571428571428571428571428571428571428571428571428571428571',200) - >>> gmpy2.get_context() - context(precision=200, real_prec=Default, imag_prec=Default, - round=RoundToNearest, real_round=Default, imag_round=Default, - emax=1073741823, emin=-1073741823, - subnormalize=False, - trap_underflow=False, underflow=False, - trap_overflow=False, overflow=False, - trap_inexact=False, inexact=True, - trap_invalid=False, invalid=False, - trap_erange=False, erange=False, - trap_divzero=False, divzero=False, - allow_complex=False, - rational_division=False, - allow_release_gil=False) - >>> mpfr(1)/0 - mpfr('inf') - >>> gmpy2.get_context().trap_divzero=True - >>> mpfr(1)/0 # doctest: +IGNORE_EXCEPTION_DETAIL +ELLIPSIS - Traceback (most recent call last): - ... - gmpy2.DivisionByZeroError: division by zero - >>> gmpy2.get_context() - context(precision=200, real_prec=Default, imag_prec=Default, - round=RoundToNearest, real_round=Default, imag_round=Default, - emax=1073741823, emin=-1073741823, - subnormalize=False, - trap_underflow=False, underflow=False, - trap_overflow=False, overflow=False, - trap_inexact=False, inexact=True, - trap_invalid=False, invalid=False, - trap_erange=False, erange=False, - trap_divzero=True, divzero=True, - allow_complex=False, - rational_division=False, - allow_release_gil=False) - >>> gmpy2.sqrt(mpfr(-2)) - mpfr('nan') - >>> gmpy2.get_context().allow_complex=True - >>> gmpy2.get_context().precision=53 - >>> gmpy2.sqrt(mpfr(-2)) - mpc('0.0+1.4142135623730951j') - >>> - >>> gmpy2.set_context(gmpy2.context()) - >>> with gmpy2.local_context() as ctx: - ... print(gmpy2.const_pi()) - ... ctx.precision+=20 - ... print(gmpy2.const_pi()) - ... ctx.precision+=20 - ... print(gmpy2.const_pi()) - ... - 3.1415926535897931 - 3.1415926535897932384628 - 3.1415926535897932384626433831 - >>> print(gmpy2.const_pi()) - 3.1415926535897931 - - -Miscellaneous gmpy2 Functions ------------------------------ - -.. autofunction:: digits -.. autofunction:: from_binary -.. autofunction:: license -.. autofunction:: mp_limbsize -.. autofunction:: mp_version -.. autofunction:: mpc_version -.. autofunction:: mpfr_version -.. autofunction:: random_state -.. autofunction:: to_binary -.. autofunction:: version - -Generic gmpy2 Functions ------------------------ - -.. autofunction:: add -.. autofunction:: div -.. autofunction:: mul -.. autofunction:: sub - -.. autofunction:: square - -.. autofunction:: f2q - -.. autofunction:: fma -.. autofunction:: fms - -.. autofunction:: cmp_abs - -Exceptions ----------- - -.. autoexception:: RangeError -.. autoexception:: InexactResultError -.. autoexception:: OverflowResultError -.. autoexception:: UnderflowResultError -.. autoexception:: InvalidOperationError -.. autoexception:: DivisionByZeroError diff --git a/docs/tutorial.rst b/docs/tutorial.rst new file mode 100644 index 00000000..1bc11426 --- /dev/null +++ b/docs/tutorial.rst @@ -0,0 +1,168 @@ +Tutorial +======== + +.. currentmodule:: gmpy2 + +Start by importing the contents of the package with: + +.. doctest:: + + >>> from gmpy2 import * + +.. note:: + + The use of ``from gmpy2 import *`` is not recommended in real code. The + names in gmpy2 have been chosen to avoid conflict with Python's builtin + names but gmpy2 does use names that may conflict with other modules or + variable names. In normal usage you’ll probably only want to import the + classes and functions that you actually need. + +Lets look first on some examples of arbitrary precision arithmetic with +integer and rational types: + +.. doctest:: + + >>> mpz(99) * 43 + mpz(4257) + >>> pow(mpz(99), 37, 59) + mpz(18) + >>> isqrt(99) + mpz(9) + >>> isqrt_rem(99) + (mpz(9), mpz(18)) + >>> gcd(123, 27) + mpz(3) + >>> lcm(123, 27) + mpz(1107) + >>> (mpz(123) + 12) / 5 + mpfr('27.0') + >>> (mpz(123) + 12) // 5 + mpz(27) + >>> (mpz(123) + 12) / 5.0 + mpfr('27.0') + >>> mpz('123') + 1 + mpz(124) + >>> 10 - mpz(1) + mpz(9) + >>> is_prime(17) + True + >>> mpz('1_000_000') + mpz(1000000) + >>> mpq(3, 7)/7 + mpq(3,49) + >>> mpq(45, 3) * mpq(11, 8) + mpq(165,8) + >>> mpq(1, 7) * 11 + mpq(11,7) + +But gmpy2 also supports correctly rounded multiple precision real and complex +arithmetic. The following example shows how to control precision settings and +rounding modes: + +.. doctest:: + + >>> mpfr('1.2') + mpfr('1.2') + >>> mpfr(float('1.2')) + mpfr('1.2') + >>> ctx = get_context() + >>> ctx.precision + 53 + >>> ctx.precision = 100 + >>> mpfr('1.2') + mpfr('1.2000000000000000000000000000006',100) + >>> mpfr(float('1.2')) + mpfr('1.1999999999999999555910790149937',100) + >>> ctx.precision = 53 + >>> ctx.round = RoundUp + >>> const_pi() + mpfr('3.1415926535897936') + >>> ctx.round = RoundToNearest + >>> const_pi() + mpfr('3.1415926535897931') + +You have seen, that if the precision is changed, then ``mpfr(float('1.2'))`` +differs from ``mpfr('1.2')``. To take advantage of the higher precision +provided by the `mpfr` type, always pass constants as strings. + +Floating point contexts also are used to control exceptional conditions. For +example, division by zero can either return a floating-point positive infinity +(default) or raise an exception. + +.. doctest:: + + >>> ctx.divzero + False + >>> mpfr(1)/0 + mpfr('inf') + >>> ctx.trap_divzero = True + >>> mpfr(1)/0 + Traceback (most recent call last): + ... + gmpy2.DivisionByZeroError: division by zero + >>> ctx.divzero + True + +Exceptions are normally raised in Python when the result of a real operation is +not defined over the reals; for example, ``math.sqrt(-2)`` will raise a +:exc:`ValueError` exception. The default context in gmpy2 implements similar +behavior, but by setting :attr:`~context.allow_complex` flag, complex results +will be returned. + +.. doctest:: + + >>> sqrt(mpfr(-2)) + mpfr('nan') + >>> ctx.allow_complex = True + >>> sqrt(mpfr(-2)) + mpc('0.0+1.4142135623730951j') + +Contexts can also be used in conjunction with Python's :keyword:`with` +statement to temporarily change the context settings for a block of code. + +.. doctest:: + + >>> with local_context() as ctx: + ... print(const_pi()) + ... ctx.precision += 20 + ... print(const_pi()) + ... + 3.1415926535897931 + 3.1415926535897932384628 + >>> print(const_pi()) + 3.1415926535897931 + +It's possible to set different precision settings for real and imaginary +components. + +.. doctest:: + + >>> ctx = get_context() + >>> ctx.real_prec = 60 + >>> ctx.imag_prec = 70 + >>> sqrt(mpc('1+2j')) + mpc('1.272019649514068965+0.78615137775742328606947j',(60,70)) + +All gmpy2 numeric types support Python's "new style" string formatting +available in `formatted string literals +`_ or with +:meth:`str.format`; see `Format Specification Mini-Language +`_ for a description +of the standard formatting syntax. The precision value optionally can be +followed by the rounding mode type ('U' to round toward plus infinity, 'D' to +round toward minus infinity, 'Y' to round away from zero, 'Z' to round toward +zero and 'N' - round to the nearest value. + +.. doctest:: + + >>> a = mpfr("1.23456") + >>> "{0:15.3f}".format(a) + ' 1.235' + >>> "{0:15.3Uf}".format(a) + ' 1.235' + >>> "{0:15.3Df}".format(a) + ' 1.234' + >>> "{0:.3Df}".format(a) + '1.234' + >>> "{0:+.3Df}".format(a) + '+1.234'