#ifndef TENSOR_FUNCTIONS_H #define TENSOR_FUNCTIONS_H #include "Fastor/meta/meta.h" #include "Fastor/tensor/Tensor.h" #include "Fastor/tensor/TensorMap.h" #include "Fastor/tensor/TensorTraits.h" namespace Fastor { /* Turns a row-major tensor to column-major */ template class TensorType, typename T, size_t ... Rest> FASTOR_INLINE Tensor tocolumnmajor(const TensorType &a) { constexpr int Dimension = sizeof...(Rest); if (Dimension < 2) { return a; } else { Tensor out; T *arr_out = out.data(); const T *a_data = a.data(); if (Dimension == 2) { constexpr FASTOR_INDEX M = get_value<1,Rest...>::value; constexpr FASTOR_INDEX N = get_value<2,Rest...>::value; for (FASTOR_INDEX i=0; i::value; std::array products_ = nprods_views, typename std_ext::make_index_sequence::type>::values; FASTOR_INDEX DimensionHolder[Dimension] = {Rest...}; std::reverse(DimensionHolder,DimensionHolder+Dimension); std::reverse(products_.begin(),products_.end()); std::array as = {}; int jt; FASTOR_INDEX counter=0; while(counter < Size) { FASTOR_INDEX index = 0; for (int ii=0; ii=0; jt--) { as[jt] +=1; if(as[jt] class TensorType, typename T, size_t ... Rest> FASTOR_INLINE Tensor torowmajor(const TensorType &a) { constexpr int Dimension = sizeof...(Rest); if (Dimension < 2) { return a; } else { Tensor out; T *arr_out = out.data(); const T *a_data = a.data(); if (Dimension == 2) { constexpr FASTOR_INDEX M = get_value<1,Rest...>::value; constexpr FASTOR_INDEX N = get_value<2,Rest...>::value; for (FASTOR_INDEX i=0; i::value; std::array products_ = nprods_views, typename std_ext::make_index_sequence::type>::values; FASTOR_INDEX DimensionHolder[Dimension] = {Rest...}; std::reverse(DimensionHolder,DimensionHolder+Dimension); std::reverse(products_.begin(),products_.end()); std::array as = {}; int jt; FASTOR_INDEX counter=0; while(counter < Size) { FASTOR_INDEX index = 0; for (int ii=0; ii=0; jt--) { as[jt] +=1; if(as[jt] class TensorType, typename T, size_t ... Rest> FASTOR_INLINE index_to_tensor_map_t> squeeze(const TensorType &a) { return index_to_tensor_map_t>(a.data()); } /* reshape - reshapes a tensor to a tensor of different shape and returns a TensorMap A TensorMap is a view in to an existing tensor so modifying the reshaped tensor will modify the original tensor and vice versa Note that you cannot call this function on tensor expressions as this is a view in to a concrete tensor type holding storage example: auto b = reshape(a); */ template FASTOR_INLINE TensorMap reshape(const Tensor &a) { static_assert(pack_prod::value==pack_prod::value, "SIZE OF TENSOR SHOULD REMAIN THE SAME DURING RESHAPE"); return TensorMap(a.data()); } /* flatten - creates a flattened 1D view of a tensor and returns a TensorMap A TensorMap is a view in to an existing tensor so modifying the reshaped tensor will modify the original tensor and vice versa Note that you cannot call this function on tensor expressions as this is a view in to a concrete tensor type holding storage example: auto b = flatten(a); */ template FASTOR_INLINE TensorMap::value> flatten(const Tensor &a) { return TensorMap::value>(a.data()); } #if FASTOR_NIL // Constant tensors static FASTOR_INLINE Tensor levi_civita_ps() { Tensor LeCi_ps; LeCi_ps(0,1,2) = 1.f; LeCi_ps(1,2,0) = 1.f; LeCi_ps(2,0,1) = 1.f; LeCi_ps(1,0,2) = -1.f; LeCi_ps(2,1,0) = -1.f; LeCi_ps(0,2,1) = -1.f; return LeCi_ps; } static FASTOR_INLINE Tensor levi_civita_pd() { Tensor LeCi_pd; LeCi_pd(0,1,2) = 1.; LeCi_pd(1,2,0) = 1.; LeCi_pd(2,0,1) = 1.; LeCi_pd(1,0,2) = -1.; LeCi_pd(2,1,0) = -1.; LeCi_pd(0,2,1) = -1.; return LeCi_pd; } template static FASTOR_INLINE Tensor kronecker_delta() { Tensor out; out.eye(); return out; } #endif } #endif // TENSOR_FUNCTIONS_H