Quantum++  v0.8.2
C++11 quantum computing library
iomanip.h
Go to the documentation of this file.
1 /*
2  * Quantum++
3  *
4  * Copyright (c) 2013 - 2015 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 // ostream manipulators for nice formatting of
31 // Eigen matrices and STL/C-style containers/vectors
32 
33 namespace qpp
34 {
35 namespace internal
36 {
37 template<typename InputIterator>
38 class IOManipRange : public IDisplay
39 {
40  InputIterator _first, _last;
41  std::string _separator, _start, _end;
42 public:
43  explicit IOManipRange(InputIterator first, InputIterator last,
44  const std::string& separator,
45  const std::string& start = "[",
46  const std::string& end = "]") :
47  _first{first},
48  _last{last},
49  _separator{separator},
50  _start{start},
51  _end{end}
52  {
53  }
54 
55  // to silence -Weffc++ warnings for classes that have pointer members
56  // (whenever we have a pointer instantiation,
57  // i.e. iterator is a raw pointer)
58  IOManipRange(const IOManipRange&) = default;
59 
60  IOManipRange& operator=(const IOManipRange&) = default;
61 
62 private:
63  std::ostream& display(std::ostream& os) const override
64  {
65  os << _start;
66 
67  bool first = true;
68  for (auto it = _first; it != _last; ++it)
69  {
70  if (!first)
71  os << _separator;
72  first = false;
73  os << *it;
74  }
75  os << _end;
76 
77  return os;
78  }
79 }; // class IOManipRange
80 
81 template<typename PointerType>
82 class IOManipPointer : public IDisplay
83 {
84  const PointerType* _p;
86  std::string _separator, _start, _end;
87 public:
88  explicit IOManipPointer(const PointerType* p, const idx n,
89  const std::string& separator,
90  const std::string& start = "[",
91  const std::string& end = "]") :
92  _p{p},
93  _n{n},
94  _separator{separator},
95  _start{start},
96  _end{end}
97  {
98  }
99 
100  // to silence -Weffc++ warnings for classes that have pointer members
101  IOManipPointer(const IOManipPointer&) = default;
102 
103  IOManipPointer& operator=(const IOManipPointer&) = default;
104 
105 private:
106  std::ostream& display(std::ostream& os) const override
107  {
108  os << _start;
109 
110  for (idx i = 0; i < _n - 1; ++i)
111  os << _p[i] << _separator;
112  if (_n > 0)
113  os << _p[_n - 1];
114 
115  os << _end;
116 
117  return os;
118  }
119 }; // class IOManipPointer
120 
121 class IOManipEigen : public IDisplay
122 {
124  double _chop;
125 public:
126  // Eigen matrices
127  template<typename Derived>
128  explicit IOManipEigen(const Eigen::MatrixBase<Derived>& A, double chop =
129  qpp::chop) :
130  _A{A.template cast<cplx>()}, _chop{chop}
131  {
132  }
133 
134  // Complex numbers
135  explicit IOManipEigen(const cplx z, double chop = qpp::chop) :
136  _A{cmat::Zero(1, 1)}, _chop{chop}
137  {
138  // put the complex number inside an Eigen matrix
139  _A(0, 0) = z;
140  }
141 
142 private:
143  std::ostream& display(std::ostream& os) const override
144  {
146  {
147  os << "Empty [" << _A.rows() << " x " << _A.cols() << "] matrix";
148 
149  return os;
150  };
151 
152  std::ostringstream ostr;
153  ostr.copyfmt(os); // copy os' state
154 
155  std::vector <std::string> vstr;
156  std::string strA;
157 
158  for (idx i = 0; i < static_cast<idx>(_A.rows()); ++i)
159  {
160  for (idx j = 0;
161  j < static_cast<idx>(_A.cols()); ++j)
162  {
163  strA.clear(); // clear the temporary string
164  ostr.clear();
165  ostr.str(std::string {}); // clear the ostringstream
166 
167  // convert to complex
168  double re = static_cast<cplx>(_A(i, j)).real();
169  double im = static_cast<cplx>(_A(i, j)).imag();
170 
171  if (std::abs(re) < _chop && std::abs(im) < _chop)
172  {
173  ostr << "0 "; // otherwise segfault on destruction
174  // if using only vstr.push_back("0 ");
175  // bug in MATLAB libmx
176  vstr.push_back(ostr.str());
177  }
178  else if (std::abs(re) < _chop)
179  {
180  ostr << im;
181  vstr.push_back(ostr.str() + "i");
182  }
183  else if (std::abs(im) < _chop)
184  {
185  ostr << re;
186  vstr.push_back(ostr.str() + " ");
187  }
188  else
189  {
190  ostr << re;
191  strA = ostr.str();
192 
193  strA += (im > 0 ? " + " : " - ");
194  ostr.clear();
195  ostr.str(std::string()); // clear
196  ostr << std::abs(im);
197  strA += ostr.str();
198  strA += "i";
199  vstr.push_back(strA);
200  }
201  }
202  }
203 
204  // determine the maximum lenght of the entries in each column
205  std::vector <idx> maxlengthcols(_A.cols(), 0);
206 
207  for (idx i = 0; i < static_cast<idx>(_A.rows());
208  ++i)
209  for (idx j = 0;
210  j < static_cast<idx>(_A.cols()); ++j)
211  if (vstr[i * _A.cols() + j].size() > maxlengthcols[j])
212  maxlengthcols[j] = vstr[i * _A.cols() + j].size();
213 
214  // finally display it!
215  for (idx i = 0; i < static_cast<idx>(_A.rows()); ++i)
216  {
217  os << std::setw(static_cast<int>(maxlengthcols[0])) << std::right
218  << vstr[i * _A.cols()]; // display first column
219  // then the rest
220  for (idx j = 1;
221  j < static_cast<idx>(_A.cols()); ++j)
222  os << std::setw(static_cast<int>(maxlengthcols[j] + 2))
223  << std::right << vstr[i * _A.cols() + j];
224 
225  if (i < static_cast<idx>(_A.rows()) - 1)
226  os << std::endl;
227  }
228 
229  return os;
230  }
231 }; // class IOManipEigen
232 
233 } /* namespace internal */
234 } /* namespace qpp */
235 
236 #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:86
IOManipEigen(const Eigen::MatrixBase< Derived > &A, double chop=qpp::chop)
Definition: iomanip.h:128
std::string _separator
Definition: iomanip.h:41
double _chop
Definition: iomanip.h:124
std::string _separator
Definition: iomanip.h:86
cmat _A
Definition: iomanip.h:123
std::ostream & display(std::ostream &os) const override
Must be overridden by all derived classes.
Definition: iomanip.h:63
Definition: iomanip.h:38
IOManipPointer & operator=(const IOManipPointer &)=default
Quantum++ main namespace.
Definition: codes.h:30
std::string _start
Definition: iomanip.h:41
std::string _end
Definition: iomanip.h:41
IOManipRange & operator=(const IOManipRange &)=default
std::ostream & display(std::ostream &os) const override
Must be overridden by all derived classes.
Definition: iomanip.h:106
std::string _end
Definition: iomanip.h:86
InputIterator _last
Definition: iomanip.h:40
Abstract class (interface) that mandates the definition of virtual std::ostream& display(std::ostream...
Definition: idisplay.h:43
Definition: iomanip.h:121
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:43
IOManipPointer(const PointerType *p, const idx n, const std::string &separator, const std::string &start="[", const std::string &end="]")
Definition: iomanip.h:88
bool _check_nonzero_size(const T &x) noexcept
Definition: util.h:113
IOManipEigen(const cplx z, double chop=qpp::chop)
Definition: iomanip.h:135
Definition: iomanip.h:82
std::ostream & display(std::ostream &os) const override
Must be overridden by all derived classes.
Definition: iomanip.h:143
const PointerType * _p
Definition: iomanip.h:84
Eigen::MatrixXcd cmat
Complex (double precision) dynamic Eigen matrix.
Definition: types.h:66
std::size_t idx
Non-negative integer index.
Definition: types.h:36
InputIterator _first
Definition: iomanip.h:40
idx _n
Definition: iomanip.h:85