polyroots-fortran: Polynomial Roots with Modern Fortran
A modern Fortran library for finding the roots of polynomials.
Many of the methods are from legacy libraries. They have been extensively modified and refactored into Modern Fortran.
Method name | Polynomial type | Coefficients | Roots | Reference |
---|---|---|---|---|
cpoly |
General | complex | complex | Jenkins & Traub (1972) |
rpoly |
General | real | complex | Jenkins & Traub (1975) |
rpzero |
General | real | complex | SLATEC |
cpzero |
General | complex | complex | SLATEC |
rpqr79 |
General | real | complex | SLATEC |
cpqr79 |
General | complex | complex | SLATEC |
dqtcrt |
Quartic | real | complex | NSWC Library |
dcbcrt |
Cubic | real | complex | NSWC Library |
dqdcrt |
Quadratic | real | complex | NSWC Library |
quadpl |
Quadratic | real | complex | NSWC Library |
dpolz |
General | real | complex | MATH77 Library |
cpolz |
General | complex | complex | MATH77 Library |
polyroots |
General | real | complex | LAPACK |
cpolyroots |
General | complex | complex | LAPACK |
rroots_chebyshev_cubic |
Cubic | real | complex | Lebedev (1991) |
qr_algeq_solver |
General | real | complex | Edelman & Murakami (1995) |
polzeros |
General | complex | complex | Bini (1996) |
cmplx_roots_gen |
General | complex | complex | Skowron & Gould (2012) |
fpml |
General | complex | complex | Cameron (2019) |
The library also includes some utility routines:
An example of using polyroots
to compute the zeros for a 5th order real polynomial
program example
use iso_fortran_env
use polyroots_module, wp => polyroots_module_rk
implicit none
integer,parameter :: degree = 5 !! polynomial degree
real(wp),dimension(degree+1) :: p = [1,2,3,4,5,6] !! coefficients
integer :: i !! counter
integer :: istatus !! status code
real(wp),dimension(degree) :: zr !! real components of roots
real(wp),dimension(degree) :: zi !! imaginary components of roots
call polyroots(degree, p, zr, zi, istatus)
write(*,'(A,1x,I3)') 'istatus: ', istatus
write(*, '(*(a22,1x))') 'real part', 'imaginary part'
do i = 1, degree
write(*,'(*(e22.15,1x))') zr(i), zi(i)
end do
end program example
The result is:
istatus: 0
real part imaginary part
0.551685463458982E+00 0.125334886027721E+01
0.551685463458982E+00 -0.125334886027721E+01
-0.149179798813990E+01 0.000000000000000E+00
-0.805786469389031E+00 0.122290471337441E+01
-0.805786469389031E+00 -0.122290471337441E+01
A fpm.toml
file is provided for compiling polyroots-fortran with the Fortran Package Manager. For example, to build:
fpm build --profile release
By default, the library is built with double precision (real64
) real values. Explicitly specifying the real kind can be done using the following processor flags:
Preprocessor flag | Kind | Number of bytes |
---|---|---|
REAL32 |
real(kind=real32) |
4 |
REAL64 |
real(kind=real64) |
8 |
REAL128 |
real(kind=real128) |
16 |
For example, to build a single precision version of the library, use:
fpm build --profile release --flag "-DREAL32"
All routines, except for polyroots
are available for any of the three real kinds. polyroots
is not available for real128
kinds since there is no corresponding LAPACK eigenvalue solver.
To run the unit tests:
fpm test
To use polyroots-fortran
within your fpm project, add the following to your fpm.toml
file:
[dependencies]
polyroots-fortran = { git="https://github.com/jacobwilliams/polyroots-fortran.git" }
or, to use a specific version:
[dependencies]
polyroots-fortran = { git="https://github.com/jacobwilliams/polyroots-fortran.git", tag = "1.2.0" }
To generate the documentation using ford, run: ford ford.md
The latest API documentation for the master
branch can be found here. This was generated from the source code using FORD.
The polyroots-fortran source code and related files and documentation are distributed under a permissive free software license (BSD-style).