Skip to content

A C++ multithreaded and multiprecision polynomial solver, i.e. a C++ class for finding in parallel the roots of complex and real polynomials of any degree in multiple precision

Notifications You must be signed in to change notification settings

cridemichel/polypp

Repository files navigation

polypp

This project provides four C++ classes (rpoly.hpp, cpoly.hpp, rpolyvp.hpp and cpolyvp.hpp) for solving complex and real polynomials of any degree in multiprecision. The rpolyvp.hpp and cpolyvp.hpp enforce a variable precision (i.e. adaptive) strategy to estimate the roots of a polynomial with a user supplied precision. Quadratic and cubic solver are based on Numerical Recipe book [1]. Quartic solvers are implemented according to Ref. [2]. Roots of polynomials of higher degree are found by using Ehrlich–Aberth algorithm as discussed in Refs. [3-5]. Stopping criterion and accurate calculation of correction term in Aberth method have been implemented as suggested in [6].

References

[1] W. H. Press, S. A. Teukolsky, W. T. Vetterling, and B. P. Flannery, Numerical Recipes - The Art of Scientific
    Computing (3rd ed.), Cambridge University Press, Cambridge, UK (2007).
[2] A. G. Orellana and C. De Michele, ACM Transactions on Mathematical Software, 46, No. 2, Article 20 (2020),
    doi: https://doi.org/10.1145/3386241.
[3] D. A. Bini, Numerical Algorithms 13, 179-200 (1996).
[4] D. A. Bini and G. Fiorentino, Numerical Algorithms 23, 127–173 (2000).
[5] D. A. Bini and L. Robol, J. Comp. and Appl. Mat. 272, 276-292 (2014).
[6] T. R. Cameron, Numerical Algorithms, 82, 1065–1084 (2019), doi: https://doi.org/10.1007/s11075-018-0641-9
[7] J. L. Aurentz et al., Siam J. Matrix Anal. Appl., 36, 3 942–973 (2015).

In addition to header files you will find some .cpp files with examples on how to use this class, a tool for a statistical analysis of solver accuracy (statanalysis) and another one for testing its performance (timingtest). Multiprecision is implemented through boost multiprecision libraries (https://www.boost.org/doc/libs/1_73_0/libs/multiprecision/doc/html/index.html) and you need to have both boost and gmp (https://gmplib.org/) installed. Boost and gmp are conveniently provided by boost and gmp homebrew packages (https://brew.sh/). Note that homebrew not only supports Mac OSX but also Linux and Windows (see https://docs.brew.sh/Homebrew-on-Linux). To build the sources you need a c++ compiler which complies with c++17. It is strongly recommended to install g++ from homebrew. The package is called gcc and it will provide the g++ executable.

The class itself can be used without boost and gmp and it does not require gcc from homebrew. This means that the poly_real example can be straightforwardly compiled by the command:

make poly_real

without installing anything else.

If you installed boost, gmp and g++ through homebrew (https://brew.sh), the Makefile should work out of the box for compiling all tools and examples, i.e. by issuing the command:

make all

the following executables will be created:

poly_real: example of usage of rpoly.hpp class for finding the roots of real polynomials.

poly_mp: example of usage of rpoly.hpp to find the roots of real polynomials in multiple precision (using boost).

poly_cmplx: example of usage of cpoly.hpp to find the roots of complex polynomials in multiple precision (using boost).

statanalysis: it performs some statistical analyses inspired by the ones which can be found in Ref. [2]. The syntax is the following:

./statanalysis <trials> <output> <sample> <degree>

where:

trials: it is the number of roots (samples A-E) or coefficients (sample F) to generate

output: every trials save the the probability distribution function P(eps_rel) in the file named PE.dat and the cumulative distribution function F(eps_rel) in the file named cumPE.dat.

sample: it is an integer between 0 and 4 which specifies the sample to generate (cf. Table 4 in Ref. [2] with 0={sample A}, 1={sample B}, 2={sample C}, 3={sample D}, 4={sample E} and 5={sample F}).

degree: degree of the polynomials.

timingtest:

this program performs a timing test of the polynomial solver. The syntax is the following:

time ./timingtest <trials>

where

is the number of quartic equations to solve.

By default a polynomial of degree 1000 with random real coefficients between -0.5 and 0.5 is used. The degree of the polynomial can be changed through the macro NDEG defined in timingtest.cpp.

accuracytest:

this program carries out several accuracy tests which can be found in Ref. [7]. The syntax is the following:

./accuracytest <test_number>

where

<test_number> is a number between 1 and 18 which identifies the test to perform (see the sources to recognize the different tests)

timingtest_vp and accuracytest_vp are the same as timingtest and accuracytest respectively, except that they use the variable precision strategy provided by the cpolyvp.hpp (or rpolyvp.hpp) class to guarantee a given output precision.

Parallelization

Parallel calculation of roots is implemeneted through OpenMP (https://www.openmp.org/). To enable the parallelization gnu gcc must be used and in the Makefile replace

PARALLEL=0

with

PARALLEL=1

then issue the commands:

> make clean
> make

and to execute the timing test in parallel, do:

> export OMP_NUM_THREADS=4
> time ./timingtest 1

where you can play with the number of threads by changing the value of the environment variable OMP_NUM_THREADES and the degree of the polynomial used for the timing test by changing the macro NDEG in the file timingtest.cpp.

For polynomials of degree less than 5 the present solver is much faster than tools like MPSolve (ver. 3.1.8, https://numpi.dm.unipi.it/software/mpsolve), while it has a comparable efficiency for higher degree polynomials. Differently from MPSolve, the present algorithms does not perform (yet) any cluster analysis to boost the convergence in case of multiple/clustered roots,

Citing

If you use polypp in your research, please consider giving proper attribution by citing the following publication:

  • A.G. Orellana and C. De Michele, Algorithm 1010: Boosting Efficiency in Solving Quartic Equations with No Compromise in Accuracy, ACM Trans. Math. Softw. 46, 20:1-20:28 (2020) https://doi.org/10.1145/3386241

Enjoy!

About

A C++ multithreaded and multiprecision polynomial solver, i.e. a C++ class for finding in parallel the roots of complex and real polynomials of any degree in multiple precision

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published