solveQuadratic.h

Go to the documentation of this file.
00001 
00016 #ifndef DLR_NUMERIC_SOLVEQUADRATIC_H
00017 #define DLR_NUMERIC_SOLVEQUADRATIC_H
00018 
00019 #include <complex>
00020 
00021 namespace dlr {
00022 
00023   namespace numeric {
00024     
00067     template <class Type>
00068     bool
00069     solveQuadratic(Type c0, Type c1, Type c2,
00070                    Type& root0, Type& root1);
00071 
00072   
00092     template <class Type>
00093     void
00094     solveQuadratic(Type c0, Type c1, Type c2,
00095                    std::complex<Type>& root0, std::complex<Type>& root1);
00096 
00097 
00114     template <class Type>
00115     void
00116     solveQuadratic(std::complex<Type> c0, std::complex<Type> c1,
00117                    std::complex<Type>& root0, std::complex<Type>& root1);
00118     
00119   
00120   } // namespace numeric
00121 
00122 } // namespace dlr
00123 
00124 
00125 /* ======== Inline and template definitions below. ======== */
00126 
00127 #include <cmath>
00128 
00129 namespace dlr {
00130 
00131   namespace numeric {
00132 
00133     // This function computes the real roots of the quadratic polynomial
00134     // c0*x^2 + c1*x + c0 = 0.
00135     template <class Type>
00136     bool
00137     solveQuadratic(Type c0, Type c1, Type c2,
00138                    Type& root0, Type& root1)
00139     {
00140       Type ss = (c1 * c1) - (static_cast<Type>(4.0) * c0 * c2);
00141       if(ss < static_cast<Type>(0.0)) {
00142         return false;
00143       }
00144       Type rt = std::sqrt(ss);
00145       if(c1 < static_cast<Type>(0.0)) {
00146         rt = -rt;
00147       }
00148       Type qq = static_cast<Type>(-0.5) * (rt + c1);
00149       root0 = qq / c0;
00150       root1 = c2 / qq;
00151       return true;
00152     }
00153 
00154 
00155 
00156     // This function computes the (possibly complex) roots of the
00157     // quadratic polynomial c0*x^2 + c1*x + c2 = 0.
00158     template <class Type>
00159     void
00160     solveQuadratic(Type c0, Type c1, Type c2,
00161                    std::complex<Type>& root0, std::complex<Type>& root1)
00162     {
00163       Type ss = (c1 * c1) - (static_cast<Type>(4.0) * c0 * c2);
00164       std::complex<Type> rt;
00165       if(ss >= static_cast<Type>(0.0)) {
00166         rt.real() = std::sqrt(ss);
00167         rt.imag() = static_cast<Type>(0.0);
00168       } else {
00169         rt.real() = static_cast<Type>(0.0);
00170         rt.imag() = std::sqrt(-ss);
00171       }
00172       if(c1 < static_cast<Type>(0.0)) {
00173         rt = -rt;
00174       }
00175       std::complex<Type> qq = static_cast<Type>(-0.5) * (rt + c1);
00176       root0 = qq / c0;
00177       root1 = c2 / qq;
00178     }
00179 
00180 
00181     // This function computes the roots of the quadratic polynomial
00182     // x^2 + c0*x + c1 = 0, where c0 and c1 are complex.
00183     template <class Type>
00184     void
00185     solveQuadratic(std::complex<Type> c0, std::complex<Type> c1,
00186                    std::complex<Type>& root0, std::complex<Type>& root1)
00187     {
00188       std::complex<Type> ss = (c0 * c0) - (static_cast<Type>(4.0) * c1);
00189       std::complex<Type> rt = std::sqrt(ss);
00190       if((c0.real() * rt.real() + c0.imag() * rt.imag())
00191          < static_cast<Type>(0.0)) {
00192         rt = -rt;
00193       }
00194       std::complex<Type> qq = static_cast<Type>(-0.5) * (rt + c0);
00195       root0 = qq;
00196 
00197       // If qq is zero, then c0 and c1 are zero, and we know the
00198       // second root.
00199       if(qq.real() || qq.imag()) {
00200         root1 = c1 / qq;
00201       } else {
00202         root1.real() = Type(0.0);
00203         root1.imag() = Type(0.0);
00204       }
00205     } 
00206     
00207   } // namespace numeric
00208 
00209 } // namespace dlr
00210 
00211 #endif /* #ifndef DLR_NUMERIC_UTILITIES_H */

Generated on Wed Nov 25 00:42:42 2009 for dlrUtilities Utility Library by  doxygen 1.5.8