102 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			C++
		
	
	
			
		
		
	
	
			102 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			C++
		
	
	
| /*
 | |
|  * Tensor5Expression.h
 | |
|  * @brief Tensor expression templates based on http://www.gps.caltech.edu/~walter/FTensor/FTensor.pdf
 | |
|  * Created on: Feb 10, 2010
 | |
|  * @author: Frank Dellaert
 | |
|  */
 | |
| 
 | |
| #pragma once
 | |
| 
 | |
| #include <iostream>
 | |
| #include "tensors.h"
 | |
| 
 | |
| namespace tensors {
 | |
| 
 | |
| 	/** templated class to interface to an object A as a rank 3 tensor */
 | |
| 	template<class A, class I, class J, class K, class L, class M> class Tensor5Expression {
 | |
| 		A iter;
 | |
| 
 | |
| 		typedef Tensor5Expression<A, I, J, K, L, M> This;
 | |
| 
 | |
| 		/** Helper class for swapping indices 3 and 4 :-) */
 | |
| 		class Swap34_ {
 | |
| 			const A iter;
 | |
| 		public:
 | |
| 			Swap34_(const A &a) :
 | |
| 				iter(a) {
 | |
| 			}
 | |
| 			double operator()(int i, int j, int k, int l, int m) const {
 | |
| 				return iter(i, j, l, k, m);
 | |
| 			}
 | |
| 		};
 | |
| 
 | |
| 	public:
 | |
| 
 | |
| 		/** constructor */
 | |
| 		Tensor5Expression(const A &a) :
 | |
| 			iter(a) {
 | |
| 		}
 | |
| 
 | |
| 		/** Print */
 | |
| 		void print(const std::string& s = "Tensor5:") const {
 | |
| 			std::cout << s << std::endl;
 | |
| 			for (int m = 0; m < M::dim; m++)
 | |
| 				for (int l = 0; l < L::dim; l++)
 | |
| 					for (int k = 0; k < K::dim; k++) {
 | |
| 						std::cout << "(m,l,k) = (" << m << "," << l << "," << k << ")"
 | |
| 								<< std::endl;
 | |
| 						for (int j = 0; j < J::dim; j++) {
 | |
| 							for (int i = 0; i < I::dim; i++)
 | |
| 								std::cout << " " << (*this)(i, j, k, l, m);
 | |
| 							std::cout << std::endl;
 | |
| 						}
 | |
| 					}
 | |
| 			std::cout << std::endl;
 | |
| 		}
 | |
| 
 | |
| 		/** swap indices */
 | |
| 		typedef Tensor5Expression<Swap34_, I, J, L, K, M> Swapped;
 | |
| 		Swapped swap34() {
 | |
| 			return Swap34_(iter);
 | |
| 		}
 | |
| 
 | |
| 		/** element access */
 | |
| 		double operator()(int i, int j, int k, int l, int m) const {
 | |
| 			return iter(i, j, k, l, m);
 | |
| 		}
 | |
| 
 | |
| 	}; // Tensor5Expression
 | |
| 
 | |
| 	/** Print */
 | |
| 	template<class A, class I, class J, class K, class L, class M>
 | |
| 	void print(const Tensor5Expression<A, I, J, K, L, M>& T,
 | |
| 			const std::string& s = "Tensor5:") {
 | |
| 		T.print(s);
 | |
| 	}
 | |
| 
 | |
| 	/** Helper class for outer product of rank3 and rank2 tensor */
 | |
| 	template<class A, class I, class J, class K, class B, class L, class M>
 | |
| 	class Rank3Rank2_ {
 | |
| 		typedef Tensor3Expression<A, I, J, K> Rank3;
 | |
| 		typedef Tensor2Expression<B, L, M> Rank2;
 | |
| 		const Rank3 iterA;
 | |
| 		const Rank2 iterB;
 | |
| 	public:
 | |
| 		Rank3Rank2_(const Rank3 &a, const Rank2 &b) :
 | |
| 			iterA(a), iterB(b) {
 | |
| 		}
 | |
| 		double operator()(int i, int j, int k, int l, int m) const {
 | |
| 			return iterA(i, j, k) * iterB(l, m);
 | |
| 		}
 | |
| 	};
 | |
| 
 | |
| 	/** outer product of rank2 and rank1 tensor */
 | |
| 	template<class A, class I, class J, class K, class B, class L, class M>
 | |
| 	inline Tensor5Expression<Rank3Rank2_<A, I, J, K, B, L, M> , I, J, K, L, M> operator*(
 | |
| 			const Tensor3Expression<A, I, J, K>& a,
 | |
| 			const Tensor2Expression<B, L, M> &b) {
 | |
| 		return Rank3Rank2_<A, I, J, K, B, L, M> (a, b);
 | |
| 	}
 | |
| 
 | |
| } // namespace tensors
 |