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