Quantum++  v0.8.6
C++11 quantum computing library
iomanip.h
Go to the documentation of this file.
1 /*
2  * Quantum++
3  *
4  * Copyright (c) 2013 - 2016 Vlad Gheorghiu (vgheorgh@gmail.com)
5  *
6  * This file is part of Quantum++.
7  *
8  * Quantum++ is free software: you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation, either version 3 of the License, or
11  * (at your option) any later version.
12  *
13  * Quantum++ is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with Quantum++. If not, see <http://www.gnu.org/licenses/>.
20  */
21 
27 #ifndef INTERNAL_CLASSES_IOMANIP_H_
28 #define INTERNAL_CLASSES_IOMANIP_H_
29 
30 namespace qpp
31 {
32 namespace internal
33 {
34 
35 // implementation details
36 namespace _details
37 {
39 {
40  template<typename T>
41  // T must support rows(), cols(), operator()(idx, idx)
42  std::ostream& _display_impl(const T& _A,
43  std::ostream& _os,
44  double _chop = qpp::chop) const
45  {
46  std::ostringstream ostr;
47  ostr.copyfmt(_os); // copy os' state
48 
49  std::vector<std::string> vstr;
50  std::string strA;
51 
52  for (idx i = 0; i < static_cast<idx>(_A.rows()); ++i)
53  {
54  for (idx j = 0;
55  j < static_cast<idx>(_A.cols()); ++j)
56  {
57  strA.clear(); // clear the temporary string
58  ostr.clear();
59  ostr.str(std::string {}); // clear the ostringstream
60 
61  // convert to complex
62  double re = static_cast<cplx>(_A(i, j)).real();
63  double im = static_cast<cplx>(_A(i, j)).imag();
64 
65  if (std::abs(re) < _chop && std::abs(im) < _chop)
66  {
67  ostr << "0 "; // otherwise segfault on destruction
68  // if using only vstr.push_back("0 ");
69  // bug in MATLAB libmx
70  vstr.push_back(ostr.str());
71  }
72  else if (std::abs(re) < _chop)
73  {
74  ostr << im;
75  vstr.push_back(ostr.str() + "i");
76  }
77  else if (std::abs(im) < _chop)
78  {
79  ostr << re;
80  vstr.push_back(ostr.str() + " ");
81  }
82  else
83  {
84  ostr << re;
85  strA = ostr.str();
86 
87  strA += (im > 0 ? " + " : " - ");
88  ostr.clear();
89  ostr.str(std::string()); // clear
90  ostr << std::abs(im);
91  strA += ostr.str();
92  strA += "i";
93  vstr.push_back(strA);
94  }
95  }
96  }
97 
98  // determine the maximum lenght of the entries in each column
99  std::vector<idx> maxlengthcols(_A.cols(), 0);
100 
101  for (idx i = 0; i < static_cast<idx>(_A.rows());
102  ++i)
103  for (idx j = 0;
104  j < static_cast<idx>(_A.cols()); ++j)
105  if (vstr[i * _A.cols() + j].size() > maxlengthcols[j])
106  maxlengthcols[j] = vstr[i * _A.cols() + j].size();
107 
108  // finally display it!
109  for (idx i = 0; i < static_cast<idx>(_A.rows()); ++i)
110  {
111  _os << std::setw(static_cast<int>(maxlengthcols[0])) << std::right
112  << vstr[i * _A.cols()]; // display first column
113  // then the rest
114  for (idx j = 1;
115  j < static_cast<idx>(_A.cols()); ++j)
116  _os << std::setw(static_cast<int>(maxlengthcols[j] + 2))
117  << std::right << vstr[i * _A.cols() + j];
118 
119  if (i < static_cast<idx>(_A.rows()) - 1)
120  _os << std::endl;
121  }
122 
123  return _os;
124  }
125 };
126 } /* namespace _details */
127 
128 // ostream manipulators for nice formatting of
129 // Eigen matrices and STL/C-style containers/vectors
130 
131 template<typename InputIterator>
132 class IOManipRange : public IDisplay
133 {
134  InputIterator _first, _last;
135  std::string _separator, _start, _end;
136 public:
137  explicit IOManipRange(InputIterator first, InputIterator last,
138  const std::string& separator,
139  const std::string& start = "[",
140  const std::string& end = "]") :
141  _first{first},
142  _last{last},
143  _separator{separator},
144  _start{start},
145  _end{end}
146  {
147  }
148 
149  // to silence -Weffc++ warnings for classes that have pointer members
150  // (whenever we have a pointer instantiation,
151  // i.e. iterator is a raw pointer)
152  IOManipRange(const IOManipRange&) = default;
153 
154  IOManipRange& operator=(const IOManipRange&) = default;
155 
156 private:
157  std::ostream& display(std::ostream& os) const override
158  {
159  os << _start;
160 
161  bool first = true;
162  for (auto it = _first; it != _last; ++it)
163  {
164  if (!first)
165  os << _separator;
166  first = false;
167  os << *it;
168  }
169  os << _end;
170 
171  return os;
172  }
173 }; // class IOManipRange
174 
175 template<typename PointerType>
176 class IOManipPointer : public IDisplay
177 {
178  const PointerType* _p;
180  std::string _separator, _start, _end;
181 public:
182  explicit IOManipPointer(const PointerType* p, idx n,
183  const std::string& separator,
184  const std::string& start = "[",
185  const std::string& end = "]") :
186  _p{p},
187  _n{n},
188  _separator{separator},
189  _start{start},
190  _end{end}
191  {
192  }
193 
194  // to silence -Weffc++ warnings for classes that have pointer members
195  IOManipPointer(const IOManipPointer&) = default;
196 
197  IOManipPointer& operator=(const IOManipPointer&) = default;
198 
199 private:
200  std::ostream& display(std::ostream& os) const override
201  {
202  os << _start;
203 
204  for (idx i = 0; i < _n - 1; ++i)
205  os << _p[i] << _separator;
206  if (_n > 0)
207  os << _p[_n - 1];
208 
209  os << _end;
210 
211  return os;
212  }
213 }; // class IOManipPointer
214 
216 {
218  double _chop;
219 public:
220  // Eigen matrices
221  template<typename Derived>
222  explicit IOManipEigen(const Eigen::MatrixBase<Derived>& A,
223  double chop = qpp::chop) :
224  _A{A.template cast<cplx>()}, // copy, so we can bind rvalues safely
225  _chop{chop}
226  {
227  }
228 
229  // Complex numbers
230  explicit IOManipEigen(const cplx z, double chop = qpp::chop) :
231  _A{cmat::Zero(1, 1)}, _chop{chop}
232  {
233  // put the complex number inside an Eigen matrix
234  _A(0, 0) = z;
235  }
236 
237 private:
238  std::ostream& display(std::ostream& os) const override
239  {
240  return _display_impl(_A, os, chop);
241  }
242 }; // class IOManipEigen
243 
244 } /* namespace internal */
245 } /* namespace qpp */
246 
247 #endif /* INTERNAL_CLASSES_IOMANIP_H_ */
constexpr double chop
Used in qpp::disp() for setting to zero numbers that have their absolute value smaller than qpp::chop...
Definition: constants.h:65
std::string _start
Definition: iomanip.h:180
IOManipEigen(const Eigen::MatrixBase< Derived > &A, double chop=qpp::chop)
Definition: iomanip.h:222
std::string _separator
Definition: iomanip.h:135
double _chop
Definition: iomanip.h:218
std::string _separator
Definition: iomanip.h:180
cmat _A
Definition: iomanip.h:217
std::ostream & display(std::ostream &os) const override
Must be overridden by all derived classes.
Definition: iomanip.h:157
Definition: iomanip.h:132
IOManipPointer & operator=(const IOManipPointer &)=default
Quantum++ main namespace.
Definition: codes.h:30
std::string _start
Definition: iomanip.h:135
std::string _end
Definition: iomanip.h:135
IOManipRange & operator=(const IOManipRange &)=default
std::ostream & display(std::ostream &os) const override
Must be overridden by all derived classes.
Definition: iomanip.h:200
std::string _end
Definition: iomanip.h:180
InputIterator _last
Definition: iomanip.h:134
IOManipPointer(const PointerType *p, idx n, const std::string &separator, const std::string &start="[", const std::string &end="]")
Definition: iomanip.h:182
Abstract class (interface) that mandates the definition of virtual std::ostream& display(std::ostream...
Definition: idisplay.h:43
Definition: iomanip.h:215
std::complex< double > cplx
Complex number in double precision.
Definition: types.h:51
IOManipRange(InputIterator first, InputIterator last, const std::string &separator, const std::string &start="[", const std::string &end="]")
Definition: iomanip.h:137
IOManipEigen(const cplx z, double chop=qpp::chop)
Definition: iomanip.h:230
Definition: iomanip.h:176
std::ostream & display(std::ostream &os) const override
Must be overridden by all derived classes.
Definition: iomanip.h:238
const PointerType * _p
Definition: iomanip.h:178
Eigen::MatrixXcd cmat
Complex (double precision) dynamic Eigen matrix.
Definition: types.h:66
std::ostream & _display_impl(const T &_A, std::ostream &_os, double _chop=qpp::chop) const
Definition: iomanip.h:42
std::size_t idx
Non-negative integer index.
Definition: types.h:36
InputIterator _first
Definition: iomanip.h:134
idx _n
Definition: iomanip.h:179