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