Skip to content

Big changes: number representation, etc #178

@fredrik-johansson

Description

@fredrik-johansson
I'm planning several extensive changes, motivated by a combination of
feature requests, realization of design mistakes, changed focus (today I'm
less interested in emulation of certain aspects of IEEE 754 arithmetic, for
example), changes in available tools (such as the availability of GMPY),
and the need to serve better as a library for SymPy and Sage (I'm by the
way being funded this summer to work on special functions for Sage via mpmath).

Here are my present plans. I'm of course very much interested in comments
and suggestions.

The mpf and mpc types will be removed. Instead there will be a single type
for representing both real and complex floats. In Python-mode, the value
will be represented by a tuple (real, imag) where a Python 0 in place of
either part represents a zero. This will eliminate much of the present
type-checking cruft (and also allow for a correct way to work with strictly
imaginary numbers without adding any additional complexity).

There will also be a type for representing rationals (both real and complex).

There will be a separate type for representing infinities and NaN.

The mpf value representation will be changed to just (man, exp) where man
can be signed; this should improve performance by reducing the amount of
data being shuffled around, given the new bit_length method in Python 2.7
(and 3.1) that will make recalculation of bc much less of a bottleneck in
Python mode. Avoiding redundant checks for inf/nan will also improve
performance.

The mpf_ and mpc_ layers will be slimmed down and used much less in favor
of more high-level code. This leads to a roughly 20-50% slowdown in
pure-Python mode in some places. However, this slowdown will be offset by
doing some things in C. The new floating-point type will easily be able to
optionally inherit from a C-defined base class (probably via GMPY, as Mario
has already done work on) that defines addition and multiplication and
other speed-critical methods.

SymPy should be able to implement a fast type for real and complex numbers
by inheriting directly from the floating-point type and overriding
appropriate fallback methods.

Special functions will use a combination of 1) high-level code, written so
as to support any number type (provided that a compatibility interface is
implemented -- in particular, such an interface will be implemented for
Python floats and complexes), and 2) low-level code for evaluating
generalized power series and the like.

Series evaluation will be implemented using a simple subset of Python that
can be compiled to Python. The compiler can just return generic code
(suitable for use with e.g. float/complex), or automatically create
fixed-point code (including replacing operations on a single complex
variable by fixed-point operations on two real variables). 

I'm now fairly confident about this approach: with the current version of
the compiler (on my hard drive) I am essentially able to generate all the
200 lines of code in _jacobi_theta_2 from a 50-line specification, and in
addition the same specification can generate fast code that evaluates
jtheta(2,z,q) for float/complex z,q.

The series compiler should also be able to insert code that checks for
cancellation and slow convergence (this is very important for
hypergeometric functions), without the need to write a lot of boilerplate
manually for each series. An intriguing possibility for the future is to go
a step further and compile series code directly to a sequence of GMP/MPIR
mpz_ operations.

Some particularly speed-critical special functions (e.g. exp, log, atan,
cos, sin) will of course retain implementations in entirely hand-written
low-level code for performance reasons.

Finally, I want to get rid of global state (mp.dps) to make mpmath easier
to use as a library and to avoid potential parallelization issues. On the
other hand, I still don't want numbers to store a prec attribute. A
possibility is to give floating-point numbers an attribute pointing to a
Context object that in turn defines precision. Then there can still be a
default global Context, but it also becomes easy to create local contexts.
Another possibility, which really is quite similar in practice, is to use
multiple classes or instances of the number type itself for varying
precisions (like Sage's variable-precision rings).

Original issue for #178: http://code.google.com/p/mpmath/issues/detail?id=138

Original author: https://code.google.com/u/111502149103757882156/

Original owner: https://code.google.com/u/111502149103757882156/

Metadata

Metadata

Labels

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions