Skip to content

Commit

Permalink
Merge pull request #230 from bluescarni/pr/real_iter
Browse files Browse the repository at this point in the history
Real improvements
  • Loading branch information
bluescarni committed Apr 24, 2020
2 parents 703c190 + a4dd939 commit 5e69839
Show file tree
Hide file tree
Showing 11 changed files with 3,377 additions and 456 deletions.
6 changes: 6 additions & 0 deletions doc/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,12 @@ New
Changes
~~~~~~~

- Improve the implementation of :cpp:class:`~mppp::real`
binary operators/functions by using the MPFR primitives
more extensively and by handling mixed-precision computations
more rigorously when one of the operands in not
a :cpp:class:`~mppp::real`
(`#230 <https://github.com/bluescarni/mppp/pull/230>`__).
- For consistency with C++20, mp++'s concepts now
use snake case notation. The concept hierarchy has also been
simplified and streamlined
Expand Down
24 changes: 20 additions & 4 deletions doc/complex128.rst
Original file line number Diff line number Diff line change
Expand Up @@ -102,18 +102,22 @@ The complex128 class
:exception unspecified: any exception raised by casting ``T`` to :cpp:class:`~mppp::real128`.

.. cpp:function:: template <complex128_interoperable T, complex128_interoperable U> constexpr explicit complex128(const T &x, const U &y)
.. cpp:function:: template <string_type T, complex128_interoperable U> explicit complex128(const T &x, const U &y)
.. cpp:function:: template <complex128_interoperable T, string_type U> explicit complex128(const T &x, const U &y)
.. cpp:function:: template <string_type T, string_type U> explicit complex128(const T &x, const U &y)

Constructor from real and imaginary parts.
Constructors from real and imaginary parts, in numerical and/or string forms.

This constructor will initialise the internal value to :math:`x+\imath y`.
These constructors will initialise the internal value to :math:`x+\imath y`.
Depending on the value and type of *x* and *y*, ``this`` may not be exactly equal
to :math:`x+\imath y` after initialisation (e.g., if *x* and *y* are very large
:cpp:class:`~mppp::integer` values).

:param x: the real part of the value that will be used for the initialisation.
:param y: the imaginary part of the value that will be used for the initialisation.

:exception unspecified: any exception raised by casting ``T`` to :cpp:class:`~mppp::real128`.
:exception unspecified: any exception raised by casting ``T`` to :cpp:class:`~mppp::real128`,
or by the constructor from string of :cpp:class:`~mppp::real128`.

.. cpp:function:: template <real128_cpp_complex T> constexpr explicit complex128(const T &c)

Expand Down Expand Up @@ -148,7 +152,8 @@ The complex128 class
complex floating-point value.
:exception unspecified: any exception thrown by memory errors in standard containers.

.. cpp:function:: explicit complex128(const char *begin, const char *end)
.. cpp:class:: char_range_t
.. cpp:function:: explicit complex128(const char *begin, const char *end, char_range_t)

Constructor from a range of characters.

Expand All @@ -158,6 +163,17 @@ The complex128 class
Internally, the constructor will copy the content of the range to a local buffer, add a string terminator, and
invoke the constructor from string.

The third argument of type :cpp:class:`~mppp::complex128::char_range_t` is used only to
prevent this constructor from competing with the binary constructors during overload resolution.

Example:

.. code-block:: c++

const char str[] = "1.23";
complex128 c{str, str + 4, complex128::char_range_t{}};
assert(c == complex128{"1.23"});

:param begin: the begin of the input range.
:param end: the end of the input range.

Expand Down
11 changes: 6 additions & 5 deletions doc/installation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ mp++ has the following dependencies:
used in the implementation of additional special functions for the
:cpp:class:`~mppp::real` class;
* the `quadmath library <https://gcc.gnu.org/onlinedocs/libquadmath/>`__ from GCC, *optional*, used
in the implementation of the :cpp:class:`~mppp::real128` class
in the implementation of the :cpp:class:`~mppp::real128` and :cpp:class:`~mppp::complex128` classes
(typically, the quadmath library is part of GCC and it does not need to
be installed separately);
* the `Boost <https://www.boost.org/>`__ libraries, *optional*, currently used
Expand Down Expand Up @@ -185,9 +185,8 @@ system you can compile this example with the following command:
Because parts of mp++ are implemented using templates,
users of the library will have to explicitly link to GMP
and (if enabled) MPFR. Explicit linking to the other optional
dependencies (quadmath, Arb, etc.) is not necessary, as they are
used only within the compiled component
of the mp++ library.
dependencies is not necessary, as they will
be automatically brought into the link chain by the mp++ library.

If you are using CMake, it is highly recommended to make use of the config-file
package provided with mp++ rather
Expand Down Expand Up @@ -272,7 +271,9 @@ Intel compiler:
as constant expressions. As a result, a few :cpp:class:`~mppp::real128`
functions which are ``constexpr`` on GCC and Clang are not ``constexpr``
when using the Intel compiler. These occurrences are marked in the API
reference.
reference. Also, the Intel compiler seems to be prone to internal
errors when performing ``constexpr`` computations with
:cpp:class:`~mppp::real128` and :cpp:class:`~mppp::complex128`.

MinGW:

Expand Down
92 changes: 22 additions & 70 deletions doc/real.rst
Original file line number Diff line number Diff line change
Expand Up @@ -33,18 +33,18 @@ The real class

.. code-block:: c++

auto x = real{5,200} + real{6,150};
auto x = real{5, 200} + real{6, 150};

the first operand has a value of 5 and precision of 200 bits, while the second operand has a value of 6 and precision
150 bits. The precision of the result ``x`` (and the precision at which the addition is computed) will be
150 bits. The precision of the result ``x`` will be
the maximum precision among the two operands, that is, 200 bits.

The precision of a :cpp:class:`~mppp::real` can be set at construction, or it can be changed later via functions
such as :cpp:func:`mppp::real::set_prec()`, :cpp:func:`mppp::real::prec_round()`, etc. By default,
the precision of a :cpp:class:`~mppp::real` is automatically deduced upon construction following a set of heuristics
aimed at ensuring that the constructed :cpp:class:`~mppp::real` preserves the value used for initialisation,
if possible.
For instance, by default, the construction of a :cpp:class:`~mppp::real` from a 32 bit integer will yield a
For instance, by default the construction of a :cpp:class:`~mppp::real` from a 32 bit integer will yield a
:cpp:class:`~mppp::real` with a precision of 32 bits. This behaviour can be altered by specifying explicitly
the desired precision value.

Expand All @@ -54,13 +54,13 @@ The real class

.. code-block:: c++

mpfr_add(rop,a,b,MPFR_RNDN);
mpfr_add(rop, a, b, MPFR_RNDN);

that writes the result of ``a + b``, rounded to nearest, into ``rop``, becomes simply

.. code-block:: c++

add(rop,a,b);
add(rop, a, b);

where the ``add()`` function is resolved via argument-dependent lookup. Function calls with overlapping arguments
are allowed, unless noted otherwise. Unless otherwise specified, the :cpp:class:`~mppp::real` API always
Expand Down Expand Up @@ -1230,7 +1230,7 @@ Arithmetic

.. versionadded:: 0.19

Ternary :cpp:class:`~mppp::real` primitives for exact
Ternary :cpp:class:`~mppp::real` primitives for
multiplication/division by powers of 2.

These functions will set *rop* to, respectively:
Expand All @@ -1239,7 +1239,6 @@ Arithmetic
* :math:`\frac{x}{2^n}` (``div_2`` variants).

The precision of the result will be equal to the precision of *x*.
The computation will be exact (that is, no rounding takes place).

:param rop: the return value.
:param x: the operand.
Expand All @@ -1254,7 +1253,7 @@ Arithmetic

.. versionadded:: 0.19

Binary :cpp:class:`~mppp::real` primitives for exact
Binary :cpp:class:`~mppp::real` primitives for
multiplication/division by powers of 2.

These functions will return, respectively:
Expand All @@ -1263,7 +1262,6 @@ Arithmetic
* :math:`\frac{x}{2^n}` (``div_2`` variants).

The precision of the result will be equal to the precision of *x*.
The computation will be exact (that is, no rounding takes place).

:param x: the operand.
:param n: the power of 2.
Expand Down Expand Up @@ -1585,18 +1583,11 @@ Exponentiation
This function will compute and return *op1* raised to the power of *op2*.
The precision of the result will be set to the largest precision among the operands.

Non-:cpp:class:`~mppp::real` operands will be converted to :cpp:class:`~mppp::real`
before performing the operation. The conversion of non-:cpp:class:`~mppp::real` operands
to :cpp:class:`~mppp::real` follows the same heuristics described in the generic assignment operator of
:cpp:class:`~mppp::real`.

:param op1: the base.
:param op2: the exponent.

:return: *op1* raised to the power of *op2*.

:exception unspecified: any exception thrown by the generic assignment operator of :cpp:class:`~mppp::real`.

.. cpp:function:: template <mppp::cvr_real T> mppp::real &mppp::sqr(mppp::real &rop, T &&op)

.. versionadded:: 0.19
Expand Down Expand Up @@ -1794,11 +1785,7 @@ Trigonometry
Binary arctangent-2.

This function will compute and return the arctangent-2 of *y* and *x*.

Non-:cpp:class:`~mppp::real` operands will be converted to :cpp:class:`~mppp::real`
before performing the operation. The conversion of non-:cpp:class:`~mppp::real` operands
to :cpp:class:`~mppp::real` follows the same heuristics described in the generic assignment
operator of :cpp:class:`~mppp::real`.
The precision of the result will be set to the largest precision among the operands.

:param y: the sine argument.
:param x: the cosine argument.
Expand Down Expand Up @@ -2012,11 +1999,7 @@ Logarithms and exponentials
Binary log hypot function.

This function will compute and return :math:`\log\left(\sqrt{x^2+y^2}\right)`.

Non-:cpp:class:`~mppp::real` operands will be converted to :cpp:class:`~mppp::real`
before performing the operation. The conversion of non-:cpp:class:`~mppp::real` operands
to :cpp:class:`~mppp::real` follows the same heuristics described in the generic assignment
operator of :cpp:class:`~mppp::real`.
The precision of the result will be set to the largest precision among the operands.

:param x: the first argument.
:param y: the second argument.
Expand Down Expand Up @@ -2131,11 +2114,7 @@ Gamma functions
Binary incomplete Gamma function.

This function will compute and return the upper incomplete Gamma function of *x* and *y*.

Non-:cpp:class:`~mppp::real` operands will be converted to :cpp:class:`~mppp::real`
before performing the operation. The conversion of non-:cpp:class:`~mppp::real` operands
to :cpp:class:`~mppp::real` follows the same heuristics described in the generic assignment
operator of :cpp:class:`~mppp::real`.
The precision of the result will be set to the largest precision among the operands.

:param x: the first argument.
:param y: the second argument.
Expand Down Expand Up @@ -2302,11 +2281,7 @@ Other special functions
Binary beta function.

This function will compute and return the beta function of *x* and *y*.

Non-:cpp:class:`~mppp::real` operands will be converted to :cpp:class:`~mppp::real`
before performing the operation. The conversion of non-:cpp:class:`~mppp::real` operands
to :cpp:class:`~mppp::real` follows the same heuristics described in the generic assignment
operator of :cpp:class:`~mppp::real`.
The precision of the result will be set to the largest precision among the operands.

:param x: the first argument.
:param y: the second argument.
Expand All @@ -2333,11 +2308,7 @@ Other special functions
Binary hypot function.

This function will compute and return :math:`\sqrt{x^2+y^2}`.

Non-:cpp:class:`~mppp::real` operands will be converted to :cpp:class:`~mppp::real`
before performing the operation. The conversion of non-:cpp:class:`~mppp::real` operands
to :cpp:class:`~mppp::real` follows the same heuristics described in the generic assignment
operator of :cpp:class:`~mppp::real`.
The precision of the result will be set to the largest precision among the operands.

:param x: the first argument.
:param y: the second argument.
Expand All @@ -2364,11 +2335,7 @@ Other special functions
Binary AGM.

This function will compute and return the arithmetic-geometric mean of *x* and *y*.

Non-:cpp:class:`~mppp::real` operands will be converted to :cpp:class:`~mppp::real`
before performing the operation. The conversion of non-:cpp:class:`~mppp::real` operands
to :cpp:class:`~mppp::real` follows the same heuristics described in the generic assignment
operator of :cpp:class:`~mppp::real`.
The precision of the result will be set to the largest precision among the operands.

:param x: the first argument.
:param y: the second argument.
Expand Down Expand Up @@ -2459,18 +2426,11 @@ Mathematical operators

The precision of the result will be set to the largest precision among the operands.

Non-:cpp:class:`~mppp::real` operands will be converted to :cpp:class:`~mppp::real`
before performing the operation. The conversion of non-:cpp:class:`~mppp::real` operands
to :cpp:class:`~mppp::real` follows the same heuristics described in the generic assignment operator of
:cpp:class:`~mppp::real`.

:param a: the first operand.
:param b: the second operand.

:return: the result of the binary operation.

:exception unspecified: any exception thrown by the generic assignment operator of :cpp:class:`~mppp::real`.

.. cpp:function:: template <typename U, mppp::real_in_place_op_types<U> T> T &mppp::operator+=(T &a, U &&b)
.. cpp:function:: template <typename U, mppp::real_in_place_op_types<U> T> T &mppp::operator-=(T &a, U &&b)
.. cpp:function:: template <typename U, mppp::real_in_place_op_types<U> T> T &mppp::operator*=(T &a, U &&b)
Expand All @@ -2497,22 +2457,20 @@ Mathematical operators
a = static_cast<T>(a * b);
a = static_cast<T>(a / b);

That is, the operation is performed via the corresponding binary operator
and the result is assigned back to *a*, after a conversion if necessary.

:param a: the first operand.
:param b: the second operand.

:return: a reference to *a*.

:exception unspecified: any exception thrown by the corresponding binary operator,
or by the generic conversion operator of :cpp:class:`~mppp::real`.
:exception unspecified: any exception thrown by the generic conversion operator of :cpp:class:`~mppp::real`.

.. cpp:function:: mppp::real &mppp::operator++(mppp::real &x)
.. cpp:function:: mppp::real &mppp::operator--(mppp::real &x)

Prefix increment/decrement.

The precision of *x* will not be altered by the increment/decrement.

:param x: the input argument.

:return: a reference to *x* after the increment/decrement.
Expand All @@ -2522,6 +2480,8 @@ Mathematical operators

Suffix increment/decrement.

The precision of *x* will not be altered by the increment/decrement.

:param x: the input argument.

:return: a copy of *x* before the increment/decrement.
Expand All @@ -2546,25 +2506,17 @@ Mathematical operators

and ``false`` otherwise.

Non-:cpp:class:`~mppp::real` operands will be converted to :cpp:class:`~mppp::real` before performing the operation.
The conversion of non-:cpp:class:`~mppp::real` operands
to :cpp:class:`~mppp::real` follows the same heuristics described in the generic assignment operator of
:cpp:class:`~mppp::real`.
The comparisons are always exact (i.e., no rounding is involved).

.. note::

These operators handle NaN in the same way specified by the IEEE floating-point
standard. :ref:`Alternative comparison functions <real_comparison>` treating NaN
specially are available.
These operators handle NaN in the same way specified by the IEEE floating-point
standard. :ref:`Alternative comparison functions <real_comparison>` treating NaN
specially are available.

:param a: the first operand.
:param b: the second operand.

:return: the result of the comparison.

:exception unspecified: any exception thrown by the generic assignment operator
of :cpp:class:`~mppp::real`.

.. _real_constants:

Constants
Expand Down

0 comments on commit 5e69839

Please sign in to comment.