#ifndef TENSOR_PRINT_H #define TENSOR_PRINT_H #include "Fastor/tensor/Tensor.h" namespace Fastor { namespace internal { template using std_matrix = typename std::vector>::type; // Generate combinations template FASTOR_INLINE std::vector> index_generator() { // Do NOT change int to size_t, comparison overflows std::vector> idx; idx.resize(pack_prod::value); std::array maxes = {M,N,Rest...}; std::array a; int i,j; std::fill(a.begin(),a.end(),0); auto counter=0; while(1) { std::vector current_idx; //current_idx.reserve(sizeof...(Rest)+2); for(i = 0; i< sizeof...(Rest)+2; i++) { current_idx.push_back(a[i]); } idx[counter] = current_idx; counter++; for(j = sizeof...(Rest)+2-1 ; j>=0 ; j--) { if(++a[j] int get_row_width(const std::ostream &os, const T *a_data, size_t size) { // compute the largest width int width = 0; for(size_t j = 0; j < size; ++j) { std::stringstream sstr; sstr.copyfmt(os); sstr << a_data[j]; width = std::max(width, int(sstr.str().length())); } return width; } template class t_type, typename T, size_t ...Rest> int get_row_width(const std::ostream &os, const t_type& a) { int width = 0; for(size_t j = 0; j < pack_prod::value; ++j) { std::stringstream sstr; sstr.copyfmt(os); sstr << a.eval_s(j); width = std::max(width, int(sstr.str().length())); } return width; } } // end of namespace internal #define FASTOR_MAKE_OS_STREAM_TENSOR0(t_type) \ template\ FASTOR_HINT_INLINE std::ostream& operator<<(std::ostream &os, const t_type &a) {\ IOFormat fmt = FASTOR_DEFINE_IO_FORMAT;\ os.precision(fmt._precision);\ os << *a.data();\ return os;\ }\ #define FASTOR_MAKE_OS_STREAM_TENSOR1(t_type) \ template \ FASTOR_HINT_INLINE std::ostream& operator<<(std::ostream &os, const t_type &a) {\ IOFormat fmt = FASTOR_DEFINE_IO_FORMAT;\ os.precision(fmt._precision);\ int width = internal::get_row_width(os, a);\ for(size_t i = 0; i < M; ++i)\ {\ os << fmt._rowprefix;\ if(width) os.width(width);\ os << a(i);\ os << fmt._rowsuffix;\ os << fmt._rowsep;\ }\ return os;\ }\ #define FASTOR_MAKE_OS_STREAM_TENSOR2(t_type) \ template \ FASTOR_HINT_INLINE std::ostream& operator<<(std::ostream &os, const t_type &a) { \ IOFormat fmt = FASTOR_DEFINE_IO_FORMAT; \ os.precision(fmt._precision); \ int width = internal::get_row_width(os, a); \ for(size_t i = 0; i < M; ++i) \ {\ os << fmt._rowprefix;\ if(width) os.width(width);\ os << a(i, 0);\ for(size_t j = 1; j < N; ++j)\ {\ os << fmt._colsep;\ if(width) os.width(width);\ os << a(i, j);\ }\ os << fmt._rowsuffix;\ if( i < M - 1)\ os << fmt._rowsep;\ }\ return os;\ }\ #define FASTOR_MAKE_OS_STREAM_TENSORn(t_type) \ template=3,bool>::type=0> \ FASTOR_HINT_INLINE std::ostream& operator<<(std::ostream &os, const t_type &a) {\ IOFormat fmt = FASTOR_DEFINE_IO_FORMAT;\ constexpr std::array DimensionHolder = {Rest...};\ constexpr int M = get_value::value;\ constexpr int N = get_value::value;\ constexpr int lastrowcol = M*N;\ constexpr size_t prods = pack_prod::value;\ std::vector> combs = internal::index_generator();\ os.precision(fmt._precision);\ int width = internal::get_row_width(os, a);\ for (size_t dims=0; dims