00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #if !defined(_XRB_POLYNOMIAL_HPP_)
00012 #define _XRB_POLYNOMIAL_HPP_
00013
00014 #include "xrb.hpp"
00015
00016 #include <set>
00017 #include <sstream>
00018 #include <vector>
00019
00020 namespace Xrb
00021 {
00022
00023 class Polynomial
00024 {
00025 public:
00026
00027 typedef std::set<Float> SolutionSet;
00028
00029 inline Polynomial ()
00030 {
00031 m.resize(1);
00032 m[0] = 0.0f;
00033 ASSERT1(IsHighestCoefficientNonZero());
00034 }
00035 inline Polynomial (Float root)
00036 {
00037 m.resize(2);
00038 m[0] = -root;
00039 m[1] = 1.0f;
00040 ASSERT1(IsHighestCoefficientNonZero());
00041 }
00042 Polynomial (Polynomial const &polynomial);
00043 ~Polynomial () { }
00044
00045 inline Uint32 Order () const
00046 {
00047 ASSERT1(m.size() > 0);
00048 return m.size() - 1;
00049 }
00050 inline Float Get (Uint32 power) const
00051 {
00052 if (power < m.size())
00053 return m[power];
00054 else
00055 return 0.0f;
00056 }
00057 inline Polynomial Derivative (Uint32 order = 1) const
00058 {
00059 Polynomial retval(*this);
00060 retval.Derive(order);
00061 return retval;
00062 }
00063 inline Polynomial Integral (Uint32 order = 1) const
00064 {
00065 Polynomial retval(*this);
00066 retval.Integrate(order);
00067 return retval;
00068 }
00069 inline void Set (Uint32 power, Float coefficient)
00070 {
00071 if (power >= m.size())
00072 m.resize(power + 1);
00073 m[power] = coefficient;
00074 Minimize();
00075 ASSERT1(IsHighestCoefficientNonZero());
00076 }
00077 inline Float operator [] (Uint32 power) const
00078 {
00079 ASSERT1(power < m.size());
00080 return m[power];
00081 }
00082
00083 Float Evaluate (Float x) const;
00084 void Derive (Uint32 order = 1);
00085 void Integrate (Uint32 order = 1);
00086 void Solve (SolutionSet *solution_set, Float tolerance) const;
00087
00088 void operator = (Polynomial const &operand);
00089
00090 inline Polynomial operator + (Polynomial const &operand) const
00091 {
00092 Polynomial retval(*this);
00093 retval += operand;
00094 return retval;
00095 }
00096 inline Polynomial operator - (Polynomial const &operand) const
00097 {
00098 Polynomial retval(*this);
00099 retval -= operand;
00100 return retval;
00101 }
00102 Polynomial operator * (Polynomial const &operand) const;
00103
00104 void operator += (Polynomial const &operand);
00105 void operator -= (Polynomial const &operand);
00106 void operator *= (Polynomial const &operand);
00107
00108 private:
00109
00110 inline bool IsHighestCoefficientNonZero () const
00111 {
00112 if (m.size() == 1)
00113 return true;
00114 else
00115 return *m.rbegin() != 0.0f;
00116 }
00117 static inline Float FastPow (Uint32 power, Float *basis_vector)
00118 {
00119 Float retval = 1.0f;
00120 while (power != 0)
00121 {
00122 if ((power & 1) != 0)
00123 retval *= *basis_vector;
00124 power >>= 1;
00125 ++basis_vector;
00126 }
00127 return retval;
00128 }
00129
00130 bool NewtonsMethod (
00131 Float *solution,
00132 Polynomial const &derivative,
00133 Float x,
00134 Float tolerance) const;
00135 Float NewtonsMethodIteration (Polynomial const &derivative, Float x) const;
00136 void Minimize () const;
00137
00138 mutable std::vector<Float> m;
00139 };
00140
00141 std::ostream &operator << (std::ostream &stream, Polynomial const &polynomial);
00142
00143 }
00144
00145 #endif // !defined(_XRB_POLYNOMIAL_HPP_)