1 //
2 //  Copyright (c) 2018-2019, Cem Bassoy, [email protected]
3 //
4 //  Distributed under the Boost Software License, Version 1.0. (See
5 //  accompanying file LICENSE_1_0.txt or copy at
6 //  http://www.boost.org/LICENSE_1_0.txt)
7 //
8 //  The authors gratefully acknowledge the support of
9 //  Fraunhofer IOSB, Ettlingen, Germany
10 //
11 
12 #ifndef BOOST_UBLAS_TENSOR_OSTREAM_HPP
13 #define BOOST_UBLAS_TENSOR_OSTREAM_HPP
14 
15 #include <ostream>
16 #include <complex>
17 
18 namespace boost {
19 namespace numeric {
20 namespace ublas {
21 namespace detail {
22 
23 template <class value_type>
print(std::ostream & out,value_type const & p)24 void print(std::ostream& out, value_type const& p)
25 {
26 	out << p << " ";
27 }
28 
29 template <class value_type>
print(std::ostream & out,const std::complex<value_type> & p)30 void print(std::ostream& out, const std::complex<value_type>& p)
31 {
32 	out << std::real(p) << "+" << std::imag(p) << "i ";
33 }
34 
35 
36 template <class size_type, class value_type>
print(std::ostream & out,size_type r,const value_type * p,const size_type * w,const size_type * n)37 void print(std::ostream& out, size_type r, const value_type* p, const size_type* w, const size_type* n)
38 {
39 
40 	if(r < 2)
41 	{
42 		out << "[ ... " << std::endl;
43 
44 		for(auto row = 0u; row < n[0]; p += w[0], ++row) // iterate over one column
45 		{
46 			auto p1 = p;
47 			for(auto col = 0u; col < n[1]; p1 += w[1], ++col) // iterate over first row
48 			{
49 				print(out,*p1);
50 			}
51 			if(row < n[0]-1)
52 				out << "; " << std::endl;
53 		}
54 		out << "]";
55 	}
56 	else
57 	{
58 		out << "cat("<< r+1 <<",..." << std::endl;
59 		for(auto d = 0u; d < n[r]-1; p += w[r], ++d){
60 			print(out, r-1, p, w, n);
61 			out << ",..." << std::endl;
62 		}
63 		print(out, r-1, p, w, n);
64 	}
65 	if(r>1)
66 		out << ")";
67 }
68 
69 ////////////////////////////
70 
71 
72 }
73 }
74 }
75 }
76 
77 
78 namespace boost {
79 namespace numeric {
80 namespace ublas {
81 
82 template<class T, class F, class A>
83 class tensor;
84 
85 template<class T, class F, class A>
86 class matrix;
87 
88 template<class T, class A>
89 class vector;
90 
91 }
92 }
93 }
94 
95 
96 template <class V, class F, class A>
operator <<(std::ostream & out,boost::numeric::ublas::tensor<V,F,A> const & t)97 std::ostream& operator << (std::ostream& out, boost::numeric::ublas::tensor<V,F,A> const& t)
98 {
99 
100 	if(t.extents().is_scalar()){
101 		out << '[';
102 		boost::numeric::ublas::detail::print(out,t[0]);
103 		out << ']';
104 	}
105 	else if(t.extents().is_vector()) {
106 		const auto& cat = t.extents().at(0) > t.extents().at(1) ? ';' : ',';
107 		out << '[';
108 		for(auto i = 0u; i < t.size()-1; ++i){
109 			boost::numeric::ublas::detail::print(out,t[i]);
110 			out << cat << ' ';
111 		}
112 		boost::numeric::ublas::detail::print(out,t[t.size()-1]);
113 		out << ']';
114 	}
115 	else{
116 		boost::numeric::ublas::detail::print(out, t.rank()-1, t.data(), t.strides().data(), t.extents().data());
117 	}
118 	return out;
119 }
120 
121 
122 #endif
123