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 #ifndef _FOURTHORDERTENSOR_HPP_
00030 #define _FOURTHORDERTENSOR_HPP_
00031
00032 #include <cassert>
00033 #include <vector>
00034
00035 #include <boost/numeric/ublas/vector.hpp>
00036 #include <boost/numeric/ublas/matrix.hpp>
00037 using namespace boost::numeric::ublas;
00038 #include "Exception.hpp"
00039
00045 template<unsigned DIM1, unsigned DIM2, unsigned DIM3, unsigned DIM4>
00046 class FourthOrderTensor
00047 {
00048 private:
00049
00050 std::vector<double> mData;
00058 unsigned GetVectorIndex(unsigned M, unsigned N, unsigned P, unsigned Q)
00059 {
00060 assert(M<DIM1);
00061 assert(N<DIM2);
00062 assert(P<DIM3);
00063 assert(Q<DIM4);
00064 return M + DIM1*N + DIM1*DIM2*P + DIM1*DIM2*DIM3*Q;
00065 }
00066
00067 public:
00068
00072 FourthOrderTensor();
00073
00082 template<unsigned CONTRACTED_DIM>
00083 void SetAsContractionOnFirstDimension(const c_matrix<double,DIM1,CONTRACTED_DIM>& rMatrix, FourthOrderTensor<CONTRACTED_DIM,DIM2,DIM3,DIM4>& rTensor);
00084
00085
00094 template<unsigned CONTRACTED_DIM>
00095 void SetAsContractionOnSecondDimension(const c_matrix<double,DIM2,CONTRACTED_DIM>& rMatrix, FourthOrderTensor<DIM1,CONTRACTED_DIM,DIM3,DIM4>& rTensor);
00096
00105 template<unsigned CONTRACTED_DIM>
00106 void SetAsContractionOnThirdDimension(const c_matrix<double,DIM3,CONTRACTED_DIM>& rMatrix, FourthOrderTensor<DIM1,DIM2,CONTRACTED_DIM,DIM4>& rTensor);
00107
00116 template<unsigned CONTRACTED_DIM>
00117 void SetAsContractionOnFourthDimension(const c_matrix<double,DIM4,CONTRACTED_DIM>& rMatrix, FourthOrderTensor<DIM1,DIM2,DIM3,CONTRACTED_DIM>& rTensor);
00118
00127 double& operator()(unsigned M, unsigned N, unsigned P, unsigned Q);
00128
00132 void Zero();
00133
00137 std::vector<double>& rGetData()
00138 {
00139 return mData;
00140 }
00141 };
00142
00144
00146
00147 template<unsigned DIM1, unsigned DIM2, unsigned DIM3, unsigned DIM4>
00148 FourthOrderTensor<DIM1,DIM2,DIM3,DIM4>::FourthOrderTensor()
00149 {
00150 unsigned size = DIM1*DIM2*DIM3*DIM4;
00151 mData.resize(size, 0.0);
00152 }
00153
00154 template<unsigned DIM1, unsigned DIM2, unsigned DIM3, unsigned DIM4>
00155 template<unsigned CONTRACTED_DIM>
00156 void FourthOrderTensor<DIM1,DIM2,DIM3,DIM4>::SetAsContractionOnFirstDimension(const c_matrix<double,DIM1,CONTRACTED_DIM>& rMatrix, FourthOrderTensor<CONTRACTED_DIM,DIM2,DIM3,DIM4>& rTensor)
00157 {
00158 Zero();
00159
00160 std::vector<double>::iterator iter = mData.begin();
00161 std::vector<double>::iterator other_tensor_iter = rTensor.rGetData().begin();
00162
00163 for (unsigned d=0; d<DIM4; d++)
00164 {
00165 for (unsigned c=0; c<DIM3; c++)
00166 {
00167 for (unsigned b=0; b<DIM2; b++)
00168 {
00169 for (unsigned a=0; a<DIM1; a++)
00170 {
00171 for (unsigned N=0; N<CONTRACTED_DIM; N++)
00172 {
00173
00174
00175
00176
00177
00178
00179
00180
00181 *iter += rMatrix(a,N) * *other_tensor_iter;
00182 other_tensor_iter++;
00183 }
00184
00185 iter++;
00186
00187 if (a != DIM1-1)
00188 {
00189 other_tensor_iter -= CONTRACTED_DIM;
00190 }
00191 }
00192 }
00193 }
00194 }
00195 }
00196
00197 template<unsigned DIM1, unsigned DIM2, unsigned DIM3, unsigned DIM4>
00198 template<unsigned CONTRACTED_DIM>
00199 void FourthOrderTensor<DIM1,DIM2,DIM3,DIM4>::SetAsContractionOnSecondDimension(const c_matrix<double,DIM2,CONTRACTED_DIM>& rMatrix, FourthOrderTensor<DIM1,CONTRACTED_DIM,DIM3,DIM4>& rTensor)
00200 {
00201 Zero();
00202
00203 std::vector<double>::iterator iter = mData.begin();
00204 std::vector<double>::iterator other_tensor_iter = rTensor.rGetData().begin();
00205
00206 for (unsigned d=0; d<DIM4; d++)
00207 {
00208 for (unsigned c=0; c<DIM3; c++)
00209 {
00210 for (unsigned b=0; b<DIM2; b++)
00211 {
00212 for (unsigned N=0; N<CONTRACTED_DIM; N++)
00213 {
00214 for (unsigned a=0; a<DIM1; a++)
00215 {
00216
00217
00218
00219
00220
00221
00222
00223
00224 *iter += rMatrix(b,N) * *other_tensor_iter;
00225 iter++;
00226 other_tensor_iter++;
00227 }
00228
00229 if (N != CONTRACTED_DIM-1)
00230 {
00231 iter -= DIM1;
00232 }
00233 }
00234 if (b != DIM2-1)
00235 {
00236 other_tensor_iter -= CONTRACTED_DIM*DIM1;
00237 }
00238 }
00239 }
00240 }
00241 }
00242
00243 template<unsigned DIM1, unsigned DIM2, unsigned DIM3, unsigned DIM4>
00244 template<unsigned CONTRACTED_DIM>
00245 void FourthOrderTensor<DIM1,DIM2,DIM3,DIM4>::SetAsContractionOnThirdDimension(const c_matrix<double,DIM3,CONTRACTED_DIM>& rMatrix, FourthOrderTensor<DIM1,DIM2,CONTRACTED_DIM,DIM4>& rTensor)
00246 {
00247 Zero();
00248
00249 std::vector<double>::iterator iter = mData.begin();
00250 std::vector<double>::iterator other_tensor_iter = rTensor.rGetData().begin();
00251
00252 for (unsigned d=0; d<DIM4; d++)
00253 {
00254 for (unsigned c=0; c<DIM3; c++)
00255 {
00256 for (unsigned N=0; N<CONTRACTED_DIM; N++)
00257 {
00258 for (unsigned b=0; b<DIM2; b++)
00259 {
00260 for (unsigned a=0; a<DIM1; a++)
00261 {
00262
00263
00264
00265
00266
00267
00268
00269
00270 *iter += rMatrix(c,N) * *other_tensor_iter;
00271 iter++;
00272 other_tensor_iter++;
00273 }
00274 }
00275
00276 if (N != CONTRACTED_DIM-1)
00277 {
00278 iter -= DIM1*DIM2;
00279 }
00280 }
00281
00282 if (c != DIM3-1)
00283 {
00284 other_tensor_iter -= CONTRACTED_DIM*DIM1*DIM2;
00285 }
00286 }
00287 }
00288 }
00289
00290 template<unsigned DIM1, unsigned DIM2, unsigned DIM3, unsigned DIM4>
00291 template<unsigned CONTRACTED_DIM>
00292 void FourthOrderTensor<DIM1,DIM2,DIM3,DIM4>::SetAsContractionOnFourthDimension(const c_matrix<double,DIM4,CONTRACTED_DIM>& rMatrix, FourthOrderTensor<DIM1,DIM2,DIM3,CONTRACTED_DIM>& rTensor)
00293 {
00294 Zero();
00295
00296 std::vector<double>::iterator iter = mData.begin();
00297 std::vector<double>::iterator other_tensor_iter = rTensor.rGetData().begin();
00298
00299 for (unsigned d=0; d<DIM4; d++)
00300 {
00301 for (unsigned N=0; N<CONTRACTED_DIM; N++)
00302 {
00303 for (unsigned c=0; c<DIM3; c++)
00304 {
00305 for (unsigned b=0; b<DIM2; b++)
00306 {
00307 for (unsigned a=0; a<DIM1; a++)
00308 {
00309
00310
00311
00312
00313
00314
00315
00316
00317 *iter += rMatrix(d,N) * *other_tensor_iter;
00318
00319 iter++;
00320 other_tensor_iter++;
00321 }
00322 }
00323 }
00324
00325 if (N != CONTRACTED_DIM-1)
00326 {
00327 iter-= DIM1*DIM2*DIM3;
00328 }
00329 }
00330
00331 other_tensor_iter -= CONTRACTED_DIM*DIM1*DIM2*DIM3;
00332 }
00333 }
00334
00335 template<unsigned DIM1, unsigned DIM2, unsigned DIM3, unsigned DIM4>
00336 double& FourthOrderTensor<DIM1,DIM2,DIM3,DIM4>::operator()(unsigned M, unsigned N, unsigned P, unsigned Q)
00337 {
00338 assert(M<DIM1);
00339 assert(N<DIM2);
00340 assert(P<DIM3);
00341 assert(Q<DIM4);
00342
00343 return mData[GetVectorIndex(M,N,P,Q)];
00344 }
00345
00346 template<unsigned DIM1, unsigned DIM2, unsigned DIM3, unsigned DIM4>
00347 void FourthOrderTensor<DIM1,DIM2,DIM3,DIM4>::Zero()
00348 {
00349 for (unsigned i=0; i<mData.size(); i++)
00350 {
00351 mData[i] = 0.0;
00352 }
00353 }
00354
00355 #endif //_FOURTHORDERTENSOR_HPP_