00001
00002
00003
00004
00005
00006
00007 #ifndef SYNAPS_MPOL_NUMEXP_H
00008 #define SYNAPS_MPOL_NUMEXP_H
00009
00010
00011 #include <iostream>
00012 #include <synaps/init.h>
00013 #include <synaps/mpol/Monom.h>
00014
00015 __BEGIN_NAMESPACE_SYNAPS
00016
00017
00018
00019 static int mask=0;
00020 template<char X, int D=2, class T=int>
00021 struct numexp {
00022 typedef int size_type;
00023 typedef T exponent_t;
00024 typedef int degree_t;
00025 typedef numexp<X,D,T> self_t;
00026
00027
00028 numexp():ind(0) {}
00029 numexp(int t):ind(0) {}
00030 numexp(const self_t &A): ind(A.ind) {}
00031 numexp(int s, int *t)
00032 {
00033 for(int i=s-1;i>=0;i--)
00034 {
00035 ind+=t[i];
00036 ind=(ind<<D);
00037 }
00038 }
00039
00040
00041 int operator != (const numexp<X,D,T>&m)
00042 {
00043 return ind!=m.ind;
00044 }
00045 int operator != (const numexp<X,D,T>&m) const
00046 {
00047 return ind!=m.ind;
00048 }
00049 exponent_t operator[](int i) const
00050 {
00051
00052 if (mask==0)
00053 {
00054 for(int j=0;j<D;j++)
00055 mask=(mask<<1)+1;
00056 }
00057 return ((mask)&(ind>>(D*i)));
00058 }
00059
00060 void reserve(int d) {};
00061 void resize(int d) {};
00062 void setExponent(int i,int d)
00063 {
00064 T tmp1=(ind>>(D*i+D))<<(D*i+D);
00065 T tmp2=0;
00066 if(mask==0)
00067 {
00068 for(int j=0;j<D;j++)
00069 mask=(mask<<1)+1;
00070 }
00071 for(int j=0;j<i;j++) tmp2=(tmp2<<D)+mask;
00072 tmp2&=ind;
00073 ind=tmp1+tmp2+(((T)d)<<(D*i));
00074 }
00075
00076
00077
00078 self_t & operator =(const numexp<X,D,T> &A)
00079 {
00080 ind=A.ind; return *this;
00081 }
00082
00083 self_t & operator += (const self_t & A)
00084 {
00085 ind+=A.ind; return *this;
00086 }
00087 self_t & operator *=(const self_t & A)
00088 {
00089 ind+=A.ind; return *this;
00090 }
00091 self_t & operator /=(const numexp<X,D,T> &A)
00092 {
00093 ind-=A.ind; return *this;
00094 }
00095
00096 bool operator == (const numexp<X,D,T> &A) const
00097 {
00098 return (ind==A.ind);
00099 }
00100
00101
00102 T ind;
00103 friend void add(numexp<X,D,T> &n,const numexp<X,D,T> &m ){
00104 n.ind+=m.ind;
00105 };
00106 };
00107
00108 template<char X,int D, class T>
00109 int Degree(const numexp<X,D,T> & m)
00110 {
00111 int d=0;
00112 for(int i=0;i<lvar(m)+1;i++) d+= m[i];
00113 return d;
00114 }
00115
00116 template<char X,int D,class T>
00117 int GDegree(const numexp<X,D,T> &A,int i)
00118 {
00119 return (3&(A.ind>>(D*i)));
00120 }
00121
00122 template<char X,int D,class T>
00123 int SDegree(numexp<X,D,T> &A,int i,int d)
00124 {
00125 int tmp1=(A.ind>>(D*i+D))<<(D*i+D);
00126 int tmp2=1;
00127 for(int j=0;j<i;j++) tmp2=(tmp2<<1)+1;
00128 tmp2&=A.ind;
00129 A.ind=tmp1+tmp2+(d<<(D*i));
00130 return A.ind;
00131 }
00132
00133 template<char X,int D,class T>
00134 int lvar(const numexp<X,D,T> &A)
00135 {
00136 int i=0;
00137 for(;(A.ind>>(D*i))>0;i++);
00138 return i-1;
00139 }
00140
00141 template<char X,int D,class T>
00142 void erase(numexp<X,D,T> &A) {}
00143
00144 template<char X,int D,class T>
00145 void add(numexp<X,D,T> &r,const numexp<X,D,T> &A,const numexp<X,D,T> &B)
00146 {
00147 r.ind=A.ind+B.ind;
00148 }
00149
00150 template<char X,int D,class T>
00151 std::ostream & operator<<(std::ostream &os, const numexp<X,D,T> & rep)
00152 {
00153
00154 T tmp;
00155 int flag=0;
00156 if (mask==0){
00157 for(int j=0;j<D;j++) mask=(mask<<1)+1;
00158 }
00159 for(int i=0;i<lvar(rep)+1;i++)
00160 {
00161 if((rep.ind>>(D*i))&mask)
00162 {
00163 if (flag)
00164 {
00165 os<<"*";
00166 }
00167 if (!flag) flag =1;
00168 os<<X<<i;
00169 if ((tmp=(rep.ind>>(D*i))&mask)>1)
00170 os<<'^'<<tmp;
00171 }
00172 }
00173 return os;
00174 }
00175
00176
00177 template <class C,char X,int D, typename T> inline
00178 void assign(Monom<C,
00179 numexp<X,D,T> > & a,
00180 const OP<'*',Monom<C,numexp<X,D,T> >,Monom<C,numexp<X,D,T> > > & M)
00181 {
00182 a.coeff() = (M.op1.coeff()*M.op2.coeff());
00183 a.rep().ind = M.op1.rep().ind;
00184 a.rep()*=M.op2.rep();
00185 }
00186
00187 template <class R,char X,int D ,typename T> inline
00188 void assign(Monom<R,numexp<X,D,T> > & res,
00189 const OP<'/',Monom<R,numexp<X,D,T> >,Monom<R,numexp<X,D,T> > > & M)
00190 {
00191 if(M.op1.nvars()< M.op2.nvars())
00192 res= Monom<R,numexp<X,D,T> >(0);
00193 else {
00194 res= Monom<R,numexp<X,D,T> >(M.op1);
00195 res.coeff() /=M.op2.coeff();
00196 for (int i = 0; i <= M.op1.nvars() && res.coeff() !=0 ; ++i)
00197 if(M.op1[i] <M.op2[i])
00198 {
00199 res= Monom<R,numexp<X,D,T> >(0);
00200 }
00201 else
00202 res.rep().setExponent(i,M.op1[i] - M.op2[i]);
00203 }
00204 }
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224 __END_NAMESPACE_SYNAPS
00225
00226 #endif // SYNAPS_MPOL_NUMEXP_H
00227
00228
00229
00230