00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #ifndef MORE_TENSIN_H
00033 #define MORE_TENSIN_H
00034
00035 #include <iosfwd>
00036 #include <more/math/math.h>
00037 #include <more/num/vectin.h>
00038
00039 #ifdef MORE_CHECK_RANGE
00040 # include <assert.h>
00041 # define MORE_CHECKRNG(i, N) assert(0 <= i && i < N)
00042 #else
00043 # define MORE_CHECKRNG(i, N)
00044 #endif
00045
00046 namespace more {
00047 namespace num {
00048
00049 template <int I> struct index {};
00050
00051 template <typename T, int N, int M>
00052 class matrin {
00053 T data[M][N];
00054 public:
00055 static const int CTC_size = M*N, CTC_size0 = N, CTC_size1 = M;
00056 typedef T scalar_type;
00057 T& operator()(int i, int j) { return data[j][i]; }
00058 T operator()(int i, int j) const { return data[j][i]; }
00059 template<typename U1, typename U2>
00060 T& operator()(U1 const& i, U2 const& j)
00061 { return (*this)(enumerator(i), enumerator(j)); }
00062 template<typename U1, typename U2>
00063 T operator()(U1 const& i, U2 const& j) const
00064 { return (*this)(enumerator(i), enumerator(j)); }
00065 static int size(int i) { return i? M : N; }
00066 static int size(index<0>) { return N; }
00067 static int size(index<1>) { return M; }
00068
00069 typedef T* storage_iterator;
00070 typedef const T* const_storage_iterator;
00071 storage_iterator storage_begin() { return &data[0][0]; }
00072 const_storage_iterator storage_begin() const { return &data[0][0]; }
00073 storage_iterator storage_end() { return &data[M-1][N-1]+1; }
00074 const_storage_iterator storage_end() const
00075 { return &data[M-1][N-1]+1; }
00076
00077 matrin& operator+=(const matrin& rhs) {
00078 for(int i = 0; i < N; ++i) for(int j = 0; j < M; ++j)
00079 data[i][j] += rhs(i, j);
00080 return *this;
00081 }
00082 matrin& operator-=(const matrin& rhs) {
00083 for(int i = 0; i < N; ++i) for(int j = 0; j < M; ++j)
00084 data[i][j] += rhs(i, j);
00085 return *this;
00086 }
00087 };
00088
00089 template<typename T, int N, int M>
00090 inline matrin<T, N, M>
00091 operator-(const matrin<T, N, M>& A) {
00092 matrin<T, N, M> C;
00093 for(int i = 0; i < N; ++i) for(int j = 0; j < M; ++j)
00094 C(i,j) = -A(i,j);
00095 return C;
00096 }
00097
00098 template<typename T, int N, int M>
00099 inline matrin<T, N, M>
00100 operator+(const matrin<T, N, M>& A, const matrin<T, N, M>& B) {
00101 matrin<T, N, M> C;
00102 for(int i = 0; i < N; ++i) for(int j = 0; j < M; ++j)
00103 C(i,j) = A(i,j) + B(i,j);
00104 return C;
00105 }
00106
00107 template<typename T, int N, int M>
00108 inline matrin<T, N, M>
00109 operator-(const matrin<T, N, M>& A, const matrin<T, N, M>& B) {
00110 matrin<T, N, M> C;
00111 for(int i = 0; i < N; ++i) for(int j = 0; j < M; ++j)
00112 C(i,j) = A(i,j) - B(i,j);
00113 return C;
00114 }
00115
00116 template<typename T, int N, int M, int L>
00117 inline matrin<T, N, L>
00118 operator*(const matrin<T, N, M>& A, const matrin<T, M, L>& B) {
00119 matrin<T, N, L> C;
00120 for(int i = 0; i < N; ++i)
00121 for(int j = 0; j < L; ++j) {
00122 T sum = 0;
00123 for(int k = 0; k < M; ++k) sum += A(i,k)*B(k,j);
00124 C(i,j) = sum;
00125 }
00126 return C;
00127 }
00128
00129
00130
00131 namespace bits {
00132 template<int M0, int M1, int M2, int M3, int M4, int M5>
00133 struct rank_finder
00134 {
00135 static const int rank =
00136 1+rank_finder<M1, M2, M3, M4, M5, 1>::rank;
00137 };
00138 template<>
00139 struct rank_finder<1, 1, 1, 1, 1, 1>
00140 {
00141 static const int rank = 0;
00142 };
00143 }
00144
00145
00146 template<typename T, int N0 = 1, int N1 = 1, int N2 = 1, int N3 = 1,
00147 int N4 = 1, int N5 = 1>
00148 class tensin {
00149 T data[N5][N4][N3][N2][N1][N0];
00150
00151 public:
00152 T& operator()(int i0 = 0, int i1 = 0, int i2 = 0, int i3 = 0,
00153 int i4 = 0, int i5 = 0)
00154 { return data[i5][i4][i3][i2][i1][i0]; }
00155 const T& operator()(int i0 = 0, int i1 = 0, int i2 = 0, int i3 = 0,
00156 int i4 = 0, int i5 = 0) const
00157 { return data[i5][i4][i3][i2][i1][i0]; }
00158 static int size() { return N0*N1*N2*N3*N4*N5; }
00159 static int size(int i) {
00160 return (i==0? N0 : (i==1? N1 :
00161 (i==2? N2 : (i==3? N3 :
00162 (i==4? N4 : N5)))));
00163 }
00164 static int size(index<0>) { return N0; }
00165 static int size(index<1>) { return N1; }
00166 static int size(index<2>) { return N2; }
00167 static int size(index<3>) { return N3; }
00168 static int size(index<4>) { return N4; }
00169 static int size(index<5>) { return N5; }
00170
00171 typedef T* iterator;
00172 typedef const T* const_iterator;
00173 typedef T scalar_type;
00174 iterator begin() { return &data[0][0][0][0][0][0]; }
00175 iterator end() {
00176 return &data[N5-1][N4-1][N3-1][N2-1][N1-1][N0-1]+1;
00177 }
00178 const_iterator begin() const { return &data[0][0][0][0][0][0]; }
00179 const_iterator end() const {
00180 return &data[N5-1][N4-1][N3-1][N2-1][N1-1][N0-1]+1;
00181 }
00182 static int rank() {
00183 return bits::rank_finder<N0, N1, N2, N3, N4, N5>::rank;
00184 }
00185 };
00186
00187 template<typename T, int N, int M>
00188 inline vectin<T, N>
00189 operator*(const matrin<T, N, M>& A, const vectin<T, M>& x) {
00190 vectin<T, N> y;
00191 for(int i = 0; i < N; ++i) {
00192 T sum = 0;
00193 for(int j = 0; j < M; ++j) sum += A(i,j)*x(j);
00194 y(i) = sum;
00195 }
00196 return y;
00197 }
00198 }}
00199
00200 #undef MORE_CHECKRNG
00201
00202 #endif