LCOV - code coverage report
Current view: top level - include/math - roots.hpp (source / functions) Coverage Total Hit
Test: mxlib Lines: 0.0 % 33 0
Test Date: 2026-08-30 22:23:37 Functions: 0.0 % 3 0

            Line data    Source code
       1              : /** \file roots.hpp
       2              :  * \author Jared R. Males (jaredmales@gmail.com)
       3              :  * \brief Declares and defines functions for finding roots
       4              :  * \ingroup gen_math_files
       5              :  *
       6              :  */
       7              : 
       8              : //***********************************************************************//
       9              : // Copyright 2015, 2016, 2017 Jared R. Males (jaredmales@gmail.com)
      10              : //
      11              : // This file is part of mxlib.
      12              : //
      13              : // mxlib is free software: you can redistribute it and/or modify
      14              : // it under the terms of the GNU General Public License as published by
      15              : // the Free Software Foundation, either version 3 of the License, or
      16              : // (at your option) any later version.
      17              : //
      18              : // mxlib is distributed in the hope that it will be useful,
      19              : // but WITHOUT ANY WARRANTY; without even the implied warranty of
      20              : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      21              : // GNU General Public License for more details.
      22              : //
      23              : // You should have received a copy of the GNU General Public License
      24              : // along with mxlib.  If not, see <http://www.gnu.org/licenses/>.
      25              : //***********************************************************************//
      26              : 
      27              : #ifndef math_roots_hpp
      28              : #define math_roots_hpp
      29              : 
      30              : #include <vector>
      31              : #include <complex>
      32              : #include <cmath>
      33              : 
      34              : namespace mx
      35              : {
      36              : namespace math
      37              : {
      38              : 
      39              : /// Calculate the descriminant for the general cubic
      40              : /**
      41              :  * \returns the descriminant
      42              :  */
      43              : template <typename realT>
      44              : realT cubicDescriminant( const realT &a, ///< [in] the 3rd order coefficient of the general cubic
      45              :                          const realT &b, ///< [in] the 2nd order coefficient of the general cubic
      46              :                          const realT &c, ///< [in] the 1st order coefficient of the general cubic
      47              :                          const realT &d  ///< [in] the 0th order coefficient of the general cubic
      48              : )
      49              : {
      50              :     return 18 * a * b * c * d - 4 * b * b * b * d + b * b * c * c - 4 * a * c * c * c - 27 * a * a * d * d;
      51              : }
      52              : 
      53              : /// Calculate the descriminant for the depressed cubic
      54              : /**
      55              :  * \returns the descriminant
      56              :  */
      57              : template <typename realT>
      58              : realT cubicDescriminant( const realT &p, ///< [in] the 0th order coefficient of the depressed cubic
      59              :                          const realT &q  ///< [in] the 0th order coefficient of the depressed cubic
      60              : )
      61              : {
      62              :     return -1 * ( 4 * p * p * p + 27 * q * q );
      63              : }
      64              : 
      65              : /// Convert a general cubic equation to depressed form
      66              : /** The general cubic is
      67              :  * \f[
      68              :  * ax^3 + bx^2 + cx + d = 0
      69              :  * \f]
      70              :  * which can be converted to compressed form
      71              :  * \f[
      72              :  * t^3 + pt + q = 0
      73              :  * \f]
      74              :  *
      75              :  */
      76              : template <typename realT>
      77            0 : void cubicDepressed( realT &p,       ///< [out] the 1st order coefficient of the depressed cubic
      78              :                      realT &q,       ///< [out] the 0th order coefficient of the depressed cubic
      79              :                      const realT &a, ///< [in] the 3rd order coefficient of the general cubic
      80              :                      const realT &b, ///< [in] the 2nd order coefficient of the general cubic
      81              :                      const realT &c, ///< [in] the 1st order coefficient of the general cubic
      82              :                      const realT &d  ///< [in] the 0th order coefficient of the general cubic
      83              : )
      84              : {
      85            0 :     p = ( 3 * a * c - b * b ) / ( 3 * a * a );
      86            0 :     q = ( 2 * b * b * b - 9 * a * b * c + 27 * a * a * d ) / ( 27 * a * a * a );
      87            0 : }
      88              : 
      89              : /// Calculate the real root for a depressed cubic with negative descriminant
      90              : /**
      91              :  * \returns the real root for a depressed cubic defined by \p p and \p q
      92              :  *
      93              :  * \throws std::runtime_error if there are 3 real roots
      94              :  *
      95              :  */
      96              : template <typename realT>
      97            0 : realT cubicRealRoot( const realT &p, ///< [in] the 1st order coefficient of the depressed cubic
      98              :                      const realT &q  ///< [in] the 0th order coefficient of the depressed cubic
      99              : )
     100              : {
     101            0 :     realT D = q * q / 4 + p * p * p / 27;
     102              : 
     103            0 :     if( D < 0 )
     104            0 :         throw std::runtime_error( "cannot apply Cardano's formula, find roots using...." );
     105              : 
     106            0 :     D = sqrt( D );
     107              : 
     108            0 :     realT u1 = -q / 2 + D;
     109            0 :     realT u2 = -q / 2 - D;
     110              : 
     111            0 :     return std::cbrt( u1 ) + std::cbrt( u2 );
     112              : }
     113              : 
     114              : /// Find the roots of the general quartic equation
     115              : /** Finds the roots of
     116              :   * \f[
     117              :     f(x) = a x^4 + b x^3 + c x^2 + d x + e
     118              :     \f]
     119              :   * using the general formula for quartic roots. See https://en.wikipedia.org/wiki/Quartic_function.
     120              :   *
     121              :   * \tparam realT is the floating point type used for calculations.
     122              :   *
     123              :   * \ingroup gen_math
     124              :   */
     125              : template <typename realT>
     126            0 : void quarticRoots( std::vector<std::complex<realT>> &x, ///< [out] On exit contains the 4 roots, is resized to length 4.
     127              :                    realT a,                             ///< [in] the coefficient of the \f$x^4\f$ term.
     128              :                    realT b,                             ///< [in] the coefficient of the \f$x^3\f$ term.
     129              :                    realT c,                             ///< [in] the coefficient of the \f$x^2\f$ term.
     130              :                    realT d,                             ///< [in] the coefficient of the \f$x^1\f$ term.
     131              :                    realT e                              ///< [in] the coefficient of the \f$x^0\f$ term.
     132              : )
     133              : {
     134            0 :     std::complex<realT> p, q, S, Q, Delta0, Delta1;
     135              : 
     136            0 :     p = ( 8.0 * a * c - 3.0 * b * b ) / ( 8.0 * a * a );
     137              : 
     138            0 :     q = ( b * b * b - 4.0 * a * b * c + 8.0 * a * a * d ) / ( 8.0 * a * a * a );
     139              : 
     140            0 :     Delta0 = c * c - 3.0 * b * d + 12.0 * a * e;
     141            0 :     Delta1 = 2.0 * c * c * c - 9.0 * b * c * d + 27.0 * b * b * e + 27.0 * a * d * d - 72.0 * a * c * e;
     142              : 
     143            0 :     Q = pow( static_cast<realT>( 0.5 ) *
     144            0 :                  ( Delta1 + sqrt( Delta1 * Delta1 - static_cast<realT>( 4 ) * Delta0 * Delta0 * Delta0 ) ),
     145            0 :              1. / 3. );
     146              : 
     147            0 :     S = static_cast<realT>( 0.5 ) *
     148            0 :         sqrt( -static_cast<realT>( 2.0 / 3.0 ) * p + static_cast<realT>( 1.0 / ( 3.0 * a ) ) * ( Q + Delta0 / Q ) );
     149              : 
     150            0 :     x.resize( 4 );
     151              : 
     152            0 :     x[0] = -b / ( 4 * a ) - S +
     153            0 :            static_cast<realT>( 0.5 ) * sqrt( static_cast<realT>( -4 ) * S * S - static_cast<realT>( 2 ) * p + q / S );
     154            0 :     x[1] = -b / ( 4 * a ) - S -
     155            0 :            static_cast<realT>( 0.5 ) * sqrt( static_cast<realT>( -4 ) * S * S - static_cast<realT>( 2 ) * p + q / S );
     156            0 :     x[2] = -b / ( 4 * a ) + S +
     157            0 :            static_cast<realT>( 0.5 ) * sqrt( static_cast<realT>( -4 ) * S * S - static_cast<realT>( 2 ) * p - q / S );
     158            0 :     x[3] = -b / ( 4 * a ) + S -
     159            0 :            static_cast<realT>( 0.5 ) * sqrt( static_cast<realT>( -4 ) * S * S - static_cast<realT>( 2 ) * p - q / S );
     160              : 
     161            0 : } // quarticRoots
     162              : 
     163              : } // namespace math
     164              : } // namespace mx
     165              : 
     166              : #endif // math_roots_hpp
        

Generated by: LCOV version 2.0-1