00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifndef DJC_COROPA_LIBALGEBRA_POLYNOMIALSH_SEEN
00019 #define DJC_COROPA_LIBALGEBRA_POLYNOMIALSH_SEEN
00020
00022
00034 template<typename SCA, typename RAT>
00035 class poly :
00036 public algebra<poly_basis<SCA, RAT> >
00037 {
00038 public:
00040 typedef poly_basis<SCA, RAT> BASIS;
00042 typedef typename BASIS::KEY KEY;
00044 typedef sparse_vector<BASIS> VECT;
00046 typedef algebra<BASIS> ALG;
00048 typedef typename ALG::iterator iterator;
00050 typedef typename ALG::const_iterator const_iterator;
00051 public:
00053 poly(void) {}
00055 poly(const poly& p) : ALG(p) {}
00057 poly(const ALG& a) : ALG(a) {}
00059 poly(const VECT& v) : ALG(v) {}
00061 explicit poly(const SCA& s) : ALG(poly::basis.empty_key, s) {}
00063 explicit poly(const KEY& k) : ALG(k) {}
00065 explicit poly(LET letter, const SCA& s)
00066 : ALG(VECT::basis.keyofletter(letter), s) {}
00067 public:
00069 inline __DECLARE_BINARY_OPERATOR(poly,*,*=,SCA)
00071 inline __DECLARE_BINARY_OPERATOR(poly,/,/=,RAT)
00073 inline __DECLARE_BINARY_OPERATOR(poly,*,*=,poly)
00075 inline __DECLARE_BINARY_OPERATOR(poly,+,+=,poly)
00077 inline __DECLARE_BINARY_OPERATOR(poly,-,-=,poly)
00079 inline __DECLARE_UNARY_OPERATOR(poly,-,-,ALG)
00081 inline SCA eval(const std::map<LET, SCA>& values) const
00082 {
00083 SCA result(VECT::zero);
00084 for (const_iterator i = VECT::begin(); i != VECT::end(); ++i)
00085 result += VECT::basis.eval_key(i->first, values) * i->second;
00086 return result;
00087 }
00088
00089 public:
00091 inline static poly prediff(const KEY& k1, const typename LET& k2)
00092 {
00093 typename KEY::iterator it;
00094 typename
00095 KEY k(k1);
00096 it = k.find(k2);
00097 poly result;
00098 if (it != k.end())
00099 {
00100 if (it->second == 1)
00101 {
00102 k.erase(it);
00103 result = poly(k);
00104 }
00105 else
00106 {
00107 SCA coeff = (it->second)--;
00108 poly temp1(k);
00109 poly temp2(coeff);
00110 result = temp2 * temp1;
00111 }
00112 }
00113 return result;
00114 }
00115 public:
00116
00118 inline static poly diff(const poly& p1, const typename LET& k2)
00119 {
00120 poly result;
00121 const_iterator it;
00122 for (it = p1.begin(); it != p1.end(); ++it)
00123 {
00124 result += poly(it->second) * prediff(it->first, k2);
00125 }
00126 return result;
00127 }
00129
00131 inline friend poly exp(const poly& arg, DEG max_degree = 3)
00132 {
00133 static KEY kunit;
00134 poly result(kunit);
00135 for (DEG i = max_degree; i >= 1; --i)
00136 {
00137 result.mul_scal_div(arg, (RAT)i);
00138 result += (poly)kunit;
00139 }
00140 return result;
00141 }
00143
00149 inline friend poly log(const poly& arg, DEG max_degree = 3)
00150 {
00151 static KEY kunit;
00152 poly tunit(kunit);
00153 poly x(arg);
00154 iterator it = x.find(kunit);
00155 if (it != x.end())
00156 x.erase(it);
00157 poly result;
00158 for (DEG i = max_degree; i >= 1; --i)
00159 {
00160 if (i % 2 == 0)
00161 result.sub_scal_div(tunit, (RAT)i);
00162 else
00163 result.add_scal_div(tunit, (RAT)i);
00164 result *= x;
00165 }
00166 return result;
00167 }
00168 };
00169
00170
00171 #endif // DJC_COROPA_LIBALGEBRA_POLYNOMIALSH_SEEN
00172
00173