00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef EXPRESSO_PERMUTATION_HDR
00022 #define EXPRESSO_PERMUTATION_HDR
00023
00024 #include "debug.h"
00025 #include "tmpltool.h"
00026 #include "ixtype.h"
00027
00028 namespace esso {
00030
00033 template<int N>
00034 class Permutation: protected Ix<N,DIMT> {
00035 public:
00036 template<int NN>
00037 friend class Permutation;
00038
00040
00041
00042 inline Permutation() {
00043 for(int n=0; n<N; n++)
00044 this->d[n]= n;
00045 }
00050 explicit inline Permutation(int r) {
00051 if(r>=0)
00052 for(int n=0; n<N; n++)
00053 this->d[n] = (n+r)%N;
00054 else
00055 for(int n=0; n<N; n++)
00056 this->d[n] = N-1-(N-1-(n+r))%N;
00057 }
00059
00060
00061
00062 inline DIMT operator[](DIMT n) const {
00063 return this->d[n];
00064 }
00066 inline bool operator == (const Permutation<N> &src) const {
00067 return Ix<N,DIMT>::operator == (src);
00068 }
00070 inline bool operator != (const Permutation<N> &src) const {
00071 return Ix<N,DIMT>::operator != (src);
00072 }
00082 template<class TT>
00083 inline Ix<N,TT> operator *(const Ix<N,TT> &i) const {
00084 Ix<N,TT> tmp;
00085 for(int n=0; n<N; n++)
00086 tmp[this->d[n]]=i[n];
00087 return tmp;
00088 }
00097 inline Permutation<N> operator *(const Permutation<N> &p) const {
00098 Permutation<N> tmp;
00099 for(int n=0; n<N; n++)
00100 tmp.d[n]=this->d[p[n]];
00101 return tmp;
00102 }
00110 inline Permutation<N> operator [](const Permutation<N> &p) const {
00111 Permutation<N> tmp;
00112 for(int n=0; n<N; n++)
00113 tmp.d[this->d[n]]=this->d[p[n]];
00114 return tmp;
00115 }
00125 inline bool IsEven() const {
00126 Permutation tmp(*this);
00127 bool iseven = true;
00128 for(int n=0; n<N-1; n++) {
00129 if(tmp[n]!=n) {
00130 int m=n+1;
00131 while(tmp[m]!=n)
00132 m++;
00133 tmp.d[m] = tmp[n];
00134 tmp.d[n] = n;
00135 iseven = !iseven;
00136 }
00137 }
00138 return iseven;
00139 }
00141
00142
00143
00147 inline bool Setup(const Ix<N,DIMT> &src) {
00148 Ix<N,DIMT> tst(0);
00149 for(int n=0; n<N; n++) {
00150 if(src[n]<0 ||src[n]>=N)
00151 return false;
00152 if(tst[n]++>0)
00153 return false;
00154 }
00155 Ix<N,DIMT>::operator =(src);
00156 return true;
00157 }
00162 inline bool SetupSwap(DIMT n1, DIMT n2) {
00163 if(n1<0 || n1>=N || n2<0 || n2>=N)
00164 return false;
00165 for(int n=0; n<N; n++)
00166 this->d[n] = n;
00167 this->d[n1] = n2;
00168 this->d[n2] = n1;
00169 return true;
00170 }
00174 inline Permutation<N> &Invert() {
00175 Permutation<N> tmp;
00176 for(int n=0; n<N; n++)
00177 tmp.d[this->d[n]]=n;
00178 return operator =(tmp);
00179 }
00183 inline Permutation<N> operator ~() const {
00184 return Permutation(*this).Invert();
00185 }
00191 template<int N1>
00192 inline Permutation<N> &Concat(const Permutation<N1> &p1,
00193 const Permutation<N-N1> &p2) {
00194 for(int n=0; n<N1; n++)
00195 this->d[n] = p1[n];
00196 for(int n=0; n<N-N1; n++)
00197 this->d[n+N1] = p2[n]+N1;
00198 return *this;
00199 }
00204 template<int M>
00205 inline Permutation<N+M> operator | (const Permutation<M> &p2) const {
00206 return Permutation<N+M>().Concat(*this,p2);
00207 }
00209 };
00210 }
00211
00212 #endif