Skip to content

Roots of a quadratic equation #674

Open
@ivan-pi

Description

@ivan-pi

Motivation

Equations such as $ax^2 + bx + c = 0$ are common across all fields of science and engineering. Often one would like to find the roots of such a quadratic equation. The solution of the quadratic is commonly given as

$$ x_{1,2} = \frac{-b \pm \sqrt{b^2 - 4ac}}{2a} $$

The formula above suffers from issues such as cancellation errors in the determinant calculation and indeterminacy when $a = 0$. Writing a robust solver which takes into account such corner cases is not a trivial feat. More details can be found under the following pages:

Prior Art

MATLAB: roots
Boost: quadratic_roots
Julia: Polynomials.roots
NAG: quadratic_​real and quadratic_​complex

Additional Information

One possible interface might look as follows:

interface quadratic_roots
  subroutine squadratic_roots(a,b,c,x0,x1)
    import sp
    real(sp), intent(in) :: a, b, c
    real(sp), intent(out) :: x0, x1
  end subroutine
  subroutine dquadratic_roots(a,b,c,x0,x1)
    import dp
    real(dp), intent(in) :: a, b, c
    real(dp), intent(out) :: x0, x1
  end subroutine
  subroutine cquadratic_roots(a,b,c,x0,x1)
    import sp
    complex(sp), intent(in) :: a, b, c
    complex(sp), intent(out) :: x0, x1
  end subroutine
  subroutine zquadratic_roots(a,b,c,x0,x1)
    import dp
    complex(dp), intent(in) :: a, b, c
    complex(dp), intent(out) :: x0, x1
  end subroutine
end interface

If bind(C) were allowed, an implementation based upon Boost C++ libraries could look as follows:

#include <boost/math/tools/roots.hpp>

#define NAME(name,kind) kind ## name

#define QUADRATIC_ROOTS(kind,T)                                  \
void NAME(quadratic_roots,kind)                                  \
  (const T* a, const T* b, const T* c, T* x0, T* x1) {           \
  auto [r0, r1] = boost::math::tools::quadratic_roots(*a,*b,*c); \
  *x0 = r0;                                                      \
  *x1 = r1;                                                      \
};

#define FOR_EACH_DATA_TYPE(X) \
  X(s,float)                  \
  X(d,double)                 \
  X(c,std::complex<float>)    \
  X(z,std::complex<double>)         

extern "C" {
FOR_EACH_DATA_TYPE(QUADRATIC_ROOTS)
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    ideaProposition of an idea and opening an issue to discuss itmediumDifficulty level is mediumtopic: mathematicslinear algebra, sparse matrices, special functions, FFT, random numbers, statistics, ...

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions