Quantum++  v1.0.0-beta1
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  } else if (std::abs(re) < chop)
72  {
73  ostr << im;
74  vstr.push_back(ostr.str() + "i");
75  } else if (std::abs(im) < chop)
76  {
77  ostr << re;
78  vstr.push_back(ostr.str() + " ");
79  } else
80  {
81  ostr << re;
82  strA = ostr.str();
83 
84  strA += (im > 0 ? " + " : " - ");
85  ostr.clear();
86  ostr.str(std::string()); // clear
87  ostr << std::abs(im);
88  strA += ostr.str();
89  strA += "i";
90  vstr.push_back(strA);
91  }
92  }
93  }
94 
95  // determine the maximum lenght of the entries in each column
96  std::vector<idx> maxlengthcols(A.cols(), 0);
97 
98  for (idx i = 0; i < static_cast<idx>(A.rows());
99  ++i)
100  for (idx j = 0;
101  j < static_cast<idx>(A.cols()); ++j)
102  if (vstr[i * A.cols() + j].size() > maxlengthcols[j])
103  maxlengthcols[j] = vstr[i * A.cols() + j].size();
104 
105  // finally display it!
106  for (idx i = 0; i < static_cast<idx>(A.rows()); ++i)
107  {
108  os << std::setw(static_cast<int>(maxlengthcols[0])) << std::right
109  << vstr[i * A.cols()]; // display first column
110  // then the rest
111  for (idx j = 1;
112  j < static_cast<idx>(A.cols()); ++j)
113  os << std::setw(static_cast<int>(maxlengthcols[j] + 2))
114  << std::right << vstr[i * A.cols() + j];
115 
116  if (i < static_cast<idx>(A.rows()) - 1)
117  os << std::endl;
118  }
119 
120  return os;
121  }
122 };
123 } /* namespace details_ */
124 
125 // ostream manipulators for nice formatting of
126 // Eigen matrices and STL/C-style containers/vectors
127 
128 template<typename InputIterator>
129 class IOManipRange : public IDisplay
130 {
131  InputIterator first_, last_;
132  std::string separator_, start_, end_;
133 public:
134  explicit IOManipRange(InputIterator first, InputIterator last,
135  const std::string& separator,
136  const std::string& start = "[",
137  const std::string& end = "]") :
138  first_{first},
139  last_{last},
140  separator_{separator},
141  start_{start},
142  end_{end}
143  {
144  }
145 
146  // to silence -Weffc++ warnings for classes that have pointer members
147  // (whenever we have a pointer instantiation,
148  // i.e. iterator is a raw pointer)
149  IOManipRange(const IOManipRange&) = default;
150 
151  IOManipRange& operator=(const IOManipRange&) = default;
152 
153 private:
154  std::ostream& display(std::ostream& os) const override
155  {
156  os << start_;
157 
158  bool first = true;
159  for (auto it = first_; it != last_; ++it)
160  {
161  if (!first)
162  os << separator_;
163  first = false;
164  os << *it;
165  }
166  os << end_;
167 
168  return os;
169  }
170 }; // class IOManipRange
171 
172 template<typename PointerType>
173 class IOManipPointer : public IDisplay
174 {
175  const PointerType* p_;
177  std::string separator_, start_, end_;
178 public:
179  explicit IOManipPointer(const PointerType* p, idx N,
180  const std::string& separator,
181  const std::string& start = "[",
182  const std::string& end = "]") :
183  p_{p},
184  N_{N},
185  separator_{separator},
186  start_{start},
187  end_{end}
188  {
189  }
190 
191  // to silence -Weffc++ warnings for classes that have pointer members
192  IOManipPointer(const IOManipPointer&) = default;
193 
194  IOManipPointer& operator=(const IOManipPointer&) = default;
195 
196 private:
197  std::ostream& display(std::ostream& os) const override
198  {
199  os << start_;
200 
201  for (idx i = 0; i < N_ - 1; ++i)
202  os << p_[i] << separator_;
203  if (N_ > 0)
204  os << p_[N_ - 1];
205 
206  os << end_;
207 
208  return os;
209  }
210 }; // class IOManipPointer
211 
213 {
215  double chop_;
216 public:
217  // Eigen matrices
218  template<typename Derived>
219  explicit IOManipEigen(const Eigen::MatrixBase<Derived>& A,
220  double chop = qpp::chop) :
221  A_{A.template cast<cplx>()}, // copy, so we can bind rvalues safely
222  chop_{chop}
223  {
224  }
225 
226  // Complex numbers
227  explicit IOManipEigen(const cplx z, double chop = qpp::chop) :
228  A_{cmat::Zero(1, 1)}, chop_{chop}
229  {
230  // put the complex number inside an Eigen matrix
231  A_(0, 0) = z;
232  }
233 
234 private:
235  std::ostream& display(std::ostream& os) const override
236  {
237  return display_impl_(A_, os, chop);
238  }
239 }; // class IOManipEigen
240 
241 } /* namespace internal */
242 } /* namespace qpp */
243 
244 #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:59
IOManipEigen(const Eigen::MatrixBase< Derived > &A, double chop=qpp::chop)
Definition: iomanip.h:219
const PointerType * p_
Definition: iomanip.h:175
std::ostream & display(std::ostream &os) const override
Must be overridden by all derived classes.
Definition: iomanip.h:154
Definition: iomanip.h:129
IOManipPointer & operator=(const IOManipPointer &)=default
Quantum++ main namespace.
Definition: codes.h:30
std::string end_
Definition: iomanip.h:132
IOManipRange & operator=(const IOManipRange &)=default
std::ostream & display(std::ostream &os) const override
Must be overridden by all derived classes.
Definition: iomanip.h:197
double chop_
Definition: iomanip.h:215
std::string separator_
Definition: iomanip.h:177
Abstract class (interface) that mandates the definition of virtual std::ostream& display(std::ostream...
Definition: idisplay.h:43
Definition: iomanip.h:212
std::complex< double > cplx
Complex number in double precision.
Definition: types.h:46
cmat A_
Definition: iomanip.h:214
IOManipRange(InputIterator first, InputIterator last, const std::string &separator, const std::string &start="[", const std::string &end="]")
Definition: iomanip.h:134
IOManipEigen(const cplx z, double chop=qpp::chop)
Definition: iomanip.h:227
Definition: iomanip.h:173
std::string start_
Definition: iomanip.h:177
std::ostream & display(std::ostream &os) const override
Must be overridden by all derived classes.
Definition: iomanip.h:235
std::string start_
Definition: iomanip.h:132
std::string separator_
Definition: iomanip.h:132
std::ostream & display_impl_(const T &A, std::ostream &os, double chop=qpp::chop) const
Definition: iomanip.h:42
Eigen::MatrixXcd cmat
Complex (double precision) dynamic Eigen matrix.
Definition: types.h:61
InputIterator first_
Definition: iomanip.h:131
idx N_
Definition: iomanip.h:176
std::size_t idx
Non-negative integer index.
Definition: types.h:36
InputIterator last_
Definition: iomanip.h:131
IOManipPointer(const PointerType *p, idx N, const std::string &separator, const std::string &start="[", const std::string &end="]")
Definition: iomanip.h:179
std::string end_
Definition: iomanip.h:177