#ifndef SINGLEVALUE_TENSOR_H #define SINGLEVALUE_TENSOR_H #include "Fastor/tensor/Tensor.h" #include "Fastor/tensor/TensorIO.h" #include "Fastor/tensor/TensorTraits.h" #include "Fastor/meta/tensor_meta.h" #include namespace Fastor { template class SingleValueTensor : public AbstractTensor,sizeof...(Rest)> { public: using scalar_type = T; using simd_vector_type = choose_best_simd_vector_t; using simd_abi_type = typename simd_vector_type::abi_type; using result_type = SingleValueTensor; using dimension_t = std::integral_constant; static constexpr FASTOR_INLINE FASTOR_INDEX rank() {return sizeof...(Rest);} static constexpr FASTOR_INLINE FASTOR_INDEX size() {return pack_prod::value;} FASTOR_INLINE FASTOR_INDEX dimension(FASTOR_INDEX dim) const { #if FASTOR_SHAPE_CHECK FASTOR_ASSERT(dim>=0 && dim < sizeof...(Rest), "TENSOR SHAPE MISMATCH"); #endif const FASTOR_INDEX DimensionHolder[sizeof...(Rest)] = {Rest...}; return DimensionHolder[dim]; } template SingleValueTensor(U num) : _data{(T)num} {} SingleValueTensor(const SingleValueTensor &a) : _data{(T)a.data()[0]} {} FASTOR_INLINE SingleValueTensor(const AbstractTensor,sizeof...(Rest)>& src_) : _data{T(0)} { } constexpr FASTOR_INLINE T* data() const { return const_cast(this->_data.data());} // Index retriever //----------------------------------------------------------------------------------------------------------// template FASTOR_INLINE int get_mem_index(U index) const { #if FASTOR_BOUNDS_CHECK FASTOR_ASSERT((index>=0 && index::value,bool>::type =0> FASTOR_INLINE int get_flat_index(Args ... args) const { #if FASTOR_BOUNDS_CHECK int largs[sizeof...(Args)] = {args...}; constexpr int DimensionHolder[dimension_t::value] = {Rest...}; for (int i=0; i=0 && largs[i] &as) const { #if FASTOR_BOUNDS_CHECK constexpr std::array products_ = nprods_views, typename std_ext::make_index_sequence::type>::values; int index = 0; for (int i=0; i=0 && index #define SCALAR_INDEXING_CONST_H //----------------------------------------------------------------------------------------------------------// // Expression templates evaluators //----------------------------------------------------------------------------------------------------------// #undef TENSOR_EVALUATOR_H #include "Fastor/tensor/TensorEvaluator.h" #define TENSOR_EVALUATOR_H //----------------------------------------------------------------------------------------------------------// // Tensor methods //----------------------------------------------------------------------------------------------------------// #undef TENSOR_METHODS_CONST_H #include "Fastor/tensor/TensorMethods.h" #define TENSOR_METHODS_CONST_H //----------------------------------------------------------------------------------------------------------// // Converters //----------------------------------------------------------------------------------------------------------// #undef PODCONVERTERS_H #include "Fastor/tensor/PODConverters.h" #define PODCONVERTERS_H //----------------------------------------------------------------------------------------------------------// // Cast method //----------------------------------------------------------------------------------------------------------// template FASTOR_INLINE SingleValueTensor cast() const { SingleValueTensor out(static_cast(_data[0])); return out; } //----------------------------------------------------------------------------------------------------------// //----------------------------------------------------------------------------------------------------------// private: const FASTOR_ALIGN std::array _data; //----------------------------------------------------------------------------------------------------------// }; // template // constexpr const T SingleValueTensor::_data[pack_prod::value]; template struct tensor_type_finder> { using type = SingleValueTensor; }; template struct scalar_type_finder> { using type = T; }; FASTOR_MAKE_OS_STREAM_TENSOR0(SingleValueTensor) FASTOR_MAKE_OS_STREAM_TENSOR1(SingleValueTensor) FASTOR_MAKE_OS_STREAM_TENSOR2(SingleValueTensor) FASTOR_MAKE_OS_STREAM_TENSORn(SingleValueTensor) template FASTOR_INLINE SingleValueTensor transpose(const SingleValueTensor &a) { return SingleValueTensor(a(0,0)); } template T trace(const SingleValueTensor &a) { return M*a(0,0); } template FASTOR_INLINE T determinant(const SingleValueTensor &a) { // determinant of a single value tensor is 0 return 0.; } template FASTOR_INLINE double norm(const SingleValueTensor &a) { return a(0,0)*std::sqrt(double(M*N)); } template FASTOR_INLINE Tensor inverse(const SingleValueTensor &a) { // A single value tensor is not invertible Tensor out(std::numeric_limits::quiet_NaN()); return out; } template FASTOR_INLINE Tensor matmul(const Tensor &a, const SingleValueTensor &b) { using V = SIMDVector; Tensor out; T *out_data = out.data(); const T *a_data = a.data(); const T b_value = b(0,0); for (size_t i=0; i FASTOR_INLINE Tensor matmul(const SingleValueTensor &a, const Tensor &b) { return transpose(matmul(transpose(b),transpose(a))); } template FASTOR_INLINE SingleValueTensor matmul(const SingleValueTensor &a, const SingleValueTensor &b) { const T a_value = a(0,0); const T b_value = b(0,0); // matmul is just this SingleValueTensor out(a_value*b_value*K); // Not necessary // using V = SIMDVector; // V vec_out; // size_t j=0; // for (; j out(out_value); return out; } // This one is almost like a compile time einsum template FASTOR_INLINE typename contraction_impl::type,SingleValueTensor, typename std_ext::make_index_sequence::type>::type einsum(const SingleValueTensor &a, const SingleValueTensor &b) { static_assert(einsum_index_checker::type>::value, "INDICES FOR EINSUM FUNCTION CANNOT APPEAR MORE THAN TWICE. USE CONTRACTION INSTEAD"); std::array idx0; std::copy_n(Index_I::_IndexHolder,Index_I::NoIndices,idx0.begin()); std::array idx1; std::copy_n(Index_J::_IndexHolder,Index_J::NoIndices,idx1.begin()); std::array dims0 = {Rest0...}; // n^2 but it is okay as this is a small loop with compile time spans size_t total = 1; for (int i=0; i::type,SingleValueTensor, typename std_ext::make_index_sequence::type>::type; OutTensor out(out_value); return out; } } // end of namespace Fastor #endif // SINGLEVALUE_TENSOR_H