|
|
|||
File indexing completed on 2026-09-12 09:17:54
0001 // Created on: 1991-05-13 0002 // Created by: Laurent PAINNOT 0003 // Copyright (c) 1991-1999 Matra Datavision 0004 // Copyright (c) 1999-2014 OPEN CASCADE SAS 0005 // 0006 // This file is part of Open CASCADE Technology software library. 0007 // 0008 // This library is free software; you can redistribute it and/or modify it under 0009 // the terms of the GNU Lesser General Public License version 2.1 as published 0010 // by the Free Software Foundation, with special exception defined in the file 0011 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT 0012 // distribution for complete text of the license and disclaimer of any warranty. 0013 // 0014 // Alternatively, this file may be used under the terms of Open CASCADE 0015 // commercial license or contractual agreement. 0016 0017 #ifndef _math_DirectPolynomialRoots_HeaderFile 0018 #define _math_DirectPolynomialRoots_HeaderFile 0019 0020 #include <Standard.hxx> 0021 #include <Standard_DefineAlloc.hxx> 0022 #include <Standard_RangeError.hxx> 0023 #include <StdFail_InfiniteSolutions.hxx> 0024 #include <Standard_Handle.hxx> 0025 0026 #include <Standard_Real.hxx> 0027 #include <Standard_OStream.hxx> 0028 0029 //! This class implements the calculation of all the real roots of a real 0030 //! polynomial of degree <= 4 using direct algebraic methods. The implementation 0031 //! uses Ferrari's method for quartics, Cardano's formula for cubics, and 0032 //! numerically stable algorithms for quadratics and linear equations. 0033 //! 0034 //! Key features: 0035 //! - Robust numerical algorithms with coefficient scaling 0036 //! - Newton-Raphson root refinement for improved accuracy 0037 //! - Proper handling of degenerate and edge cases 0038 //! - Multiple root detection and infinite solution handling 0039 //! - Scientific reference ordering for deterministic results 0040 //! 0041 //! Once found, all roots are polished using the Newton-Raphson method 0042 //! to achieve maximum numerical precision. 0043 class math_DirectPolynomialRoots 0044 { 0045 public: 0046 DEFINE_STANDARD_ALLOC 0047 0048 //! Computes all the real roots of the quartic polynomial 0049 //! Ax^4 + Bx^3 + Cx^2 + Dx + E = 0 using Ferrari's method. 0050 //! 0051 //! The algorithm: 0052 //! 1. Checks for degree reduction (A ~= 0) 0053 //! 2. Normalizes and scales coefficients for numerical stability 0054 //! 3. Solves Ferrari's resolvent cubic equation 0055 //! 4. Factors quartic into two quadratic equations 0056 //! 5. Solves both quadratics independently 0057 //! 6. Refines all roots using Newton-Raphson method 0058 //! 0059 //! @param theA coefficient of x^4 term 0060 //! @param theB coefficient of x^3 term 0061 //! @param theC coefficient of x^2 term 0062 //! @param theD coefficient of x term 0063 //! @param theE constant term 0064 Standard_EXPORT math_DirectPolynomialRoots(const double theA, 0065 const double theB, 0066 const double theC, 0067 const double theD, 0068 const double theE); 0069 0070 //! Computes all the real roots of the cubic polynomial 0071 //! Ax^3 + Bx^2 + Cx + D = 0 using Cardano's method with Vieta substitution. 0072 //! 0073 //! The algorithm: 0074 //! 1. Transforms to depressed cubic t^3 + Pt + Q = 0 0075 //! 2. Computes discriminant Delta = -4P^3/27 - Q^2/4 0076 //! 3. Uses trigonometric method for Delta < 0 (three real roots) 0077 //! 4. Uses Cardano's formula for Delta > 0 (one real root) 0078 //! 5. Handles multiple roots when Delta = 0 0079 //! 6. Applies Newton-Raphson refinement 0080 //! 0081 //! @param theA coefficient of x^3 term 0082 //! @param theB coefficient of x^2 term 0083 //! @param theC coefficient of x term 0084 //! @param theD constant term 0085 Standard_EXPORT math_DirectPolynomialRoots(const double theA, 0086 const double theB, 0087 const double theC, 0088 const double theD); 0089 0090 //! Computes all the real roots of the quadratic polynomial 0091 //! Ax^2 + Bx + C = 0 using numerically stable formulas. 0092 //! 0093 //! The algorithm avoids catastrophic cancellation by using: 0094 //! - Discriminant with error bounds: Delta = B^2 - 4AC 0095 //! - Stable root formulas based on sign of B 0096 //! - Newton-Raphson refinement for improved accuracy 0097 //! 0098 //! @param theA coefficient of x^2 term 0099 //! @param theB coefficient of x term 0100 //! @param theC constant term 0101 Standard_EXPORT math_DirectPolynomialRoots(const double theA, 0102 const double theB, 0103 const double theC); 0104 0105 //! Computes the real root of the linear equation Ax + B = 0. 0106 //! 0107 //! Handles all cases: 0108 //! - A != 0: unique solution x = -B/A 0109 //! - A = 0, B != 0: no solution (inconsistent) 0110 //! - A = 0, B = 0: infinite solutions (identity) 0111 //! 0112 //! @param theA coefficient of x term 0113 //! @param theB constant term 0114 Standard_EXPORT math_DirectPolynomialRoots(const double theA, const double theB); 0115 0116 //! Returns true if the computations are successful, otherwise returns false. 0117 //! Computations may fail due to numerical issues or overflow conditions. 0118 bool IsDone() const; 0119 0120 //! Returns true if there is an infinity of roots, otherwise returns false. 0121 //! This occurs only for the degenerate linear case 0*x + 0 = 0. 0122 bool InfiniteRoots() const; 0123 0124 //! Returns the number of distinct real roots found. 0125 //! An exception is raised if there are an infinity of roots. 0126 //! For multiple roots, this counts each root according to its multiplicity. 0127 int NbSolutions() const; 0128 0129 //! Returns the value of the Nth root in default ordering. 0130 //! The default ordering may vary depending on the algorithm used. 0131 //! An exception is raised if there are an infinity of roots. 0132 //! Exception RangeError is raised if theIndex is < 1 0133 //! or theIndex > NbSolutions. 0134 //! 0135 //! @param theIndex root index (1-based) 0136 //! @return root value 0137 double Value(const int theIndex) const; 0138 0139 //! Prints diagnostic information about the current state of the solver. 0140 //! Outputs computation status, number of roots, and individual root values. 0141 //! This method is used to redefine the operator << for debugging purposes. 0142 //! 0143 //! @param theStream output stream for diagnostic information 0144 Standard_EXPORT void Dump(Standard_OStream& theStream) const; 0145 0146 protected: 0147 //! Solves quartic equation Ax^4 + Bx^3 + Cx^2 + Dx + E = 0 using Ferrari's method 0148 //! with modern numerical enhancements for stability and accuracy. 0149 //! 0150 //! Implementation details: 0151 //! - Degree reduction check for nearly-zero leading coefficient 0152 //! - Coefficient normalization and scaling for numerical stability 0153 //! - Ferrari's resolvent cubic construction and solution 0154 //! - Quartic factorization into two quadratic equations 0155 //! - Newton-Raphson refinement of all roots 0156 //! 0157 //! @param theA coefficient of x^4 term 0158 //! @param theB coefficient of x^3 term 0159 //! @param theC coefficient of x^2 term 0160 //! @param theD coefficient of x term 0161 //! @param theE constant term 0162 Standard_EXPORT void Solve(const double theA, 0163 const double theB, 0164 const double theC, 0165 const double theD, 0166 const double theE); 0167 0168 //! Solves cubic equation Ax^3 + Bx^2 + Cx + D = 0 using Cardano's method 0169 //! with Vieta substitution and trigonometric solution for stability. 0170 //! 0171 //! Implementation features: 0172 //! - Transformation to depressed cubic form 0173 //! - Discriminant-based method selection 0174 //! - Trigonometric solution for three real roots 0175 //! - Cardano's formula for one real root 0176 //! - Special handling for multiple roots 0177 //! - Coefficient scaling for numerical robustness 0178 //! 0179 //! @param theA coefficient of x^3 term 0180 //! @param theB coefficient of x^2 term 0181 //! @param theC coefficient of x term 0182 //! @param theD constant term 0183 Standard_EXPORT void Solve(const double theA, 0184 const double theB, 0185 const double theC, 0186 const double theD); 0187 0188 //! Solves quadratic equation Ax^2 + Bx + C = 0 using numerically stable 0189 //! formulas to avoid catastrophic cancellation. 0190 //! 0191 //! Features: 0192 //! - Discriminant computation with error bounds 0193 //! - Stable root extraction formulas 0194 //! - Proper handling of near-zero discriminant (double roots) 0195 //! - Newton-Raphson refinement 0196 //! 0197 //! @param theA coefficient of x^2 term 0198 //! @param theB coefficient of x term 0199 //! @param theC constant term 0200 Standard_EXPORT void Solve(const double theA, const double theB, const double theC); 0201 0202 //! Solves linear equation Ax + B = 0 with proper handling of degenerate cases. 0203 //! 0204 //! Handles all cases: 0205 //! - Normal case (A != 0): unique solution 0206 //! - Inconsistent case (A = 0, B != 0): no solution 0207 //! - Identity case (A = 0, B = 0): infinite solutions 0208 //! 0209 //! @param theA coefficient of x term 0210 //! @param theB constant term 0211 Standard_EXPORT void Solve(const double theA, const double theB); 0212 0213 private: 0214 bool myDone; //!< Computation status flag 0215 bool myInfiniteStatus; //!< Infinite solutions flag (0*x + 0 = 0) 0216 int myNbSol; //!< Number of real roots found (0 to 4) 0217 double myRoots[4]; //!< Array storing computed real roots 0218 }; 0219 0220 inline bool math_DirectPolynomialRoots::IsDone() const 0221 { 0222 return myDone; 0223 } 0224 0225 inline bool math_DirectPolynomialRoots::InfiniteRoots() const 0226 { 0227 return myInfiniteStatus; 0228 } 0229 0230 inline int math_DirectPolynomialRoots::NbSolutions() const 0231 { 0232 StdFail_InfiniteSolutions_Raise_if(myInfiniteStatus, " "); 0233 return myNbSol; 0234 } 0235 0236 inline double math_DirectPolynomialRoots::Value(const int theIndex) const 0237 { 0238 StdFail_InfiniteSolutions_Raise_if(myInfiniteStatus, " "); 0239 Standard_RangeError_Raise_if((theIndex < 1) || (theIndex > myNbSol), " "); 0240 return myRoots[theIndex - 1]; 0241 } 0242 0243 inline Standard_OStream& operator<<(Standard_OStream& theStream, 0244 const math_DirectPolynomialRoots& theRoots) 0245 { 0246 theRoots.Dump(theStream); 0247 return theStream; 0248 } 0249 0250 #endif // _math_DirectPolynomialRoots_HeaderFile
| [ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
|
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
|