Degenerate Conic

Algorithms • Modern Fortran Programming • Orbital Mechanics

May 30, 2026

Polynomial Roots

Consider the problem of finding all the roots of a polynomial. This involves solving the following equation:

$$a_0 + a_1 x + a_2 x^2 + \cdots + a_n x^n = 0$$

This problem occurs in many different applications, such as computing atmospheric density in a spacecraft orbit simulation. In general, both the coefficients and roots can be complex numbers. A special case involves only real coefficients. General methods exist for any degree polynomial, and custom methods also exist for polynomials of specific degree. The quadratic formula is the most famous analytical solution for polynomials of degree 2. In general, numerical methods are necessary to solve polynomials of degree 5 and higher.

Newton's method is frequently used, which requires an initial guess and an iterative procedure. Another elegant way to solve for all the roots at once is to find the eigenvalues of the companion matrix.

Fortran library

polyroots-fortran

My polyroots-fortran library includes various methods to solve this problem. Many of the implementations have legacy going back decades (for example, from SLATEC). It's easy to incorporate into other codes using the Fortran Package Manager. The available methods in the library are:

Method name Polynomial type Coefficients Reference
cpoly General complex Jenkins & Traub (1972)
rpoly General real Jenkins & Traub (1975)
rpzero General real SLATEC
cpzero General complex SLATEC
rpqr79 General real SLATEC
cpqr79 General complex SLATEC
dqtcrt Quartic real NSWC Library
dcbcrt Cubic real NSWC Library
dqdcrt Quadratic real NSWC Library
quadpl Quadratic real NSWC Library
dpolz General real MATH77 Library
cpolz General complex MATH77 Library
polyroots General real LAPACK
cpolyroots General complex LAPACK
rroots_chebyshev_cubic Cubic real Lebedev (1991)
qr_algeq_solver General real Edelman & Murakami (1995)
polzeros General complex Bini (1996)
cmplx_roots_gen General complex Skowron & Gould (2012)
fpml General complex Cameron (2019)

Example

As an example, let's generate a plot of all the roots for all \(11^{th}\) degree polynomials with coefficients either +1 or -1. That is:

\(a_0\) \(a_1\) \(a_2\) \(a_3\) \(a_4\) \(a_5\) \(a_6\) \(a_7\) \(a_8\) \(a_9\) \(a_{10}\) \(a_{11}\)
-1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
-1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 1
-1 -1 -1 -1 -1 -1 -1 -1 -1 -1 1 -1
-1 -1 -1 -1 -1 -1 -1 -1 -1 -1 1 1
-1 -1 -1 -1 -1 -1 -1 -1 -1 1 -1 -1
-1 -1 -1 -1 -1 -1 -1 -1 -1 1 -1 1
-1 -1 -1 -1 -1 -1 -1 -1 -1 1 1 -1
-1 -1 -1 -1 -1 -1 -1 -1 -1 1 1 1
\(\vdots\) \(\vdots\) \(\vdots\) \(\vdots\) \(\vdots\) \(\vdots\) \(\vdots\) \(\vdots\) \(\vdots\) \(\vdots\) \(\vdots\) \(\vdots\)
1 1 1 1 1 1 1 1 1 1 1 1

We'll use the polyroots method, which solves for the roots of a real polynomial equation by computing the eigenvalues of the companion matrix (using the LAPACK eigen solver DGEEV). To get all the coefficient permutations, we will use a recursive algorithm, and pyplot-fortran to generate the plot. Here is the code:

program main

use polyroots_module, only: polyroots, wp => polyroots_module_rk
use pyplot_module,    only: pyplot

implicit none

integer,parameter :: degree = 11 !! polynomial degree
integer,dimension(2) :: icoeffs = [-1,1] !! set of coefficients
integer,dimension(degree+1) :: a !! coefficients of polynomial
type(pyplot) :: plt  !! for making the plot
integer      :: ierr !! error code from [[polyroots]]
integer      :: j    !! counter

call plt%initialize(grid=.true.,xlabel='$\\Re(z)$',ylabel='$\\Im(z)$',&
                    title='Degree 11 Polynomial Roots',usetex=.true.,&
                    font_size=30, axes_labelsize=30, &
                    xtick_labelsize=30, ytick_labelsize=30, &
                    figsize=[20,10])
call generate(1)
call plt%showfig()

contains

    recursive subroutine generate(i)
    integer, intent(in) :: i
    integer :: ix
    real(wp),dimension(degree) :: zr, zi !! roots
    if (i > degree+1) then
        ! solve for this root and add it to the plot:
        call polyroots(degree,real(a,wp),zr,zi,ierr)
        call plt%add_plot(zr,zi,label='',linestyle='bo',markersize=2)
    else
        do ix = 1,size(icoeffs)
            a(i) = icoeffs(ix)
            call generate(i+1)
        end do
    end if
    end subroutine generate

end program main

The first set of roots, for \(a = [-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1]\), are: [\(-1\), \(\pm i\), \(\pm \sqrt3/2 \pm 0.5 i\), \(\pm 0.5 \pm \sqrt3/2\)].

The resultant plot with all the roots is shown here:

roots_11

References