Quantum++  v1.0.0-beta2
C++11 quantum computing library
input_output.h
Go to the documentation of this file.
1 /*
2  * Quantum++
3  *
4  * Copyright (c) 2013 - 2017 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 INPUT_OUTPUT_H_
28 #define INPUT_OUTPUT_H_
29 
30 // input/output
31 
32 namespace qpp
33 {
34 
42 template<typename Derived>
43 internal::IOManipEigen disp(const Eigen::MatrixBase<Derived>& A,
44  double chop = qpp::chop)
45 {
46  return internal::IOManipEigen(A, chop);
47 }
48 
58 {
59  return internal::IOManipEigen(z, chop);
60 }
61 
72 template<typename InputIterator>
74  InputIterator last,
75  const std::string& separator,
76  const std::string& start = "[",
77  const std::string& end = "]")
78 {
80  first, last, separator, start, end);
81 }
82 
93 template<typename Container>
95  const Container& c, const std::string& separator,
96  const std::string& start = "[", const std::string& end = "]",
97  typename std::enable_if<is_iterable<Container>::value>::type* = nullptr)
98 {
100  std::begin(c), std::end(c), separator, start, end);
101 }
102 
113 template<typename PointerType>
115  const std::string& separator,
116  const std::string& start = "[",
117  const std::string& end = "]")
118 {
119  return internal::IOManipPointer<PointerType>(p, N, separator, start, end);
120 }
121 
130 template<typename Derived>
131 void save(const Eigen::MatrixBase<Derived>& A, const std::string& fname)
132 {
133  const dyn_mat<typename Derived::Scalar>& rA = A.derived();
134 
135  // EXCEPTION CHECKS
136 
137  // check zero-size
139  throw Exception("qpp::save()", Exception::Type::ZERO_SIZE);
140 
141  std::fstream fout;
142  fout.open(fname, std::ios::out | std::ios::binary);
143 
144  if (fout.fail())
145  {
146  throw std::runtime_error(
147  "qpp::save(): Error writing output file \""
148  + std::string(fname) + "\"!");
149  }
150  // END EXCEPTION CHECKS
151 
152  // write the header to file
153  const std::string header_ = "TYPE::Eigen::Matrix";
154  fout.write(header_.c_str(), header_.length());
155 
156  idx rows = static_cast<idx>(rA.rows());
157  idx cols = static_cast<idx>(rA.cols());
158  fout.write(reinterpret_cast<const char*>(&rows), sizeof(rows));
159  fout.write(reinterpret_cast<const char*>(&cols), sizeof(cols));
160 
161  fout.write(reinterpret_cast<const char*>(rA.data()),
162  sizeof(typename Derived::Scalar) * rows * cols);
163 
164  fout.close();
165 }
166 
184 template<typename Derived>
185 dyn_mat<typename Derived::Scalar> load(const std::string& fname)
186 {
187  std::fstream fin;
188  fin.open(fname, std::ios::in | std::ios::binary);
189 
190  // EXCEPTION CHECKS
191 
192  if (fin.fail())
193  {
194  throw std::runtime_error(
195  "qpp::load(): Error opening input file \""
196  + std::string(fname) + "\"!");
197  }
198 
199  const std::string header_ = "TYPE::Eigen::Matrix";
200  std::unique_ptr<char[]> fheader_{new char[header_.length()]};
201 
202  // read the header from file
203  fin.read(fheader_.get(), header_.length());
204  if (std::string(fheader_.get(), header_.length()) != header_)
205  {
206  throw std::runtime_error(
207  "qpp::load(): Input file \"" + std::string(fname)
208  + "\" is corrupted!");
209  }
210  // END EXCEPTION CHECKS
211 
212  idx rows, cols;
213  fin.read(reinterpret_cast<char*>(&rows), sizeof(rows));
214  fin.read(reinterpret_cast<char*>(&cols), sizeof(cols));
215 
216  dyn_mat<typename Derived::Scalar> A(rows, cols);
217 
218  fin.read(reinterpret_cast<char*>(A.data()),
219  sizeof(typename Derived::Scalar) * rows * cols);
220 
221  fin.close();
222 
223  return A;
224 }
225 
226 } /* namespace qpp */
227 
228 #endif /* INPUT_OUTPUT_H_ */
bool check_nonzero_size(const T &x) noexcept
Definition: util.h:127
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
Eigen::Matrix< Scalar, Eigen::Dynamic, Eigen::Dynamic > dyn_mat
Dynamic Eigen matrix over the field specified by Scalar.
Definition: types.h:78
Definition: iomanip.h:38
Quantum++ main namespace.
Definition: codes.h:30
Checks whether T is compatible with an STL-like iterable container.
Definition: traits.h:52
Definition: iomanip.h:121
std::complex< double > cplx
Complex number in double precision.
Definition: types.h:46
Generates custom exceptions, used when validating function parameters.
Definition: exception.h:39
Definition: iomanip.h:82
dyn_mat< typename Derived::Scalar > load(const std::string &fname)
Loads Eigen matrix from a binary file (internal format) in double precision.
Definition: input_output.h:185
void save(const Eigen::MatrixBase< Derived > &A, const std::string &fname)
Saves Eigen expression to a binary file (internal format) in double precision.
Definition: input_output.h:131
std::size_t idx
Non-negative integer index.
Definition: types.h:36
internal::IOManipEigen disp(const Eigen::MatrixBase< Derived > &A, double chop=qpp::chop)
Eigen expression ostream manipulator.
Definition: input_output.h:43