Quantum++  v1.0-rc2
A modern 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 namespace qpp
31 {
39 template<typename Derived>
40 internal::IOManipEigen disp(const Eigen::MatrixBase<Derived>& A,
41  double chop = qpp::chop)
42 {
43  return internal::IOManipEigen(A, chop);
44 }
45 
55 {
56  return internal::IOManipEigen(z, chop);
57 }
58 
69 template<typename InputIterator>
71  InputIterator last,
72  const std::string& separator,
73  const std::string& start = "[",
74  const std::string& end = "]")
75 {
77  first, last, separator, start, end);
78 }
79 
90 template<typename Container>
92  const Container& c, const std::string& separator,
93  const std::string& start = "[", const std::string& end = "]",
94  typename std::enable_if<is_iterable<Container>::value>::type* = nullptr)
95 {
97  std::begin(c), std::end(c), separator, start, end);
98 }
99 
110 template<typename PointerType>
112  const std::string& separator,
113  const std::string& start = "[",
114  const std::string& end = "]")
115 {
116  return internal::IOManipPointer<PointerType>(p, N, separator, start, end);
117 }
118 
127 template<typename Derived>
128 void save(const Eigen::MatrixBase<Derived>& A, const std::string& fname)
129 {
130  const dyn_mat<typename Derived::Scalar>& rA = A.derived();
131 
132  // EXCEPTION CHECKS
133 
134  // check zero-size
136  throw exception::ZeroSize("qpp::save()");
137 
138  std::fstream fout;
139  fout.open(fname, std::ios::out | std::ios::binary);
140 
141  if (fout.fail())
142  {
143  throw std::runtime_error(
144  "qpp::save(): Error writing output file \""
145  + std::string(fname) + "\"!");
146  }
147  // END EXCEPTION CHECKS
148 
149  // write the header to file
150  const std::string header_ = "TYPE::Eigen::Matrix";
151  fout.write(header_.c_str(), header_.length());
152 
153  idx rows = static_cast<idx>(rA.rows());
154  idx cols = static_cast<idx>(rA.cols());
155  fout.write(reinterpret_cast<const char*>(&rows), sizeof(rows));
156  fout.write(reinterpret_cast<const char*>(&cols), sizeof(cols));
157 
158  fout.write(reinterpret_cast<const char*>(rA.data()),
159  sizeof(typename Derived::Scalar) * rows * cols);
160 
161  fout.close();
162 }
163 
181 template<typename Derived>
182 dyn_mat<typename Derived::Scalar> load(const std::string& fname)
183 {
184  std::fstream fin;
185  fin.open(fname, std::ios::in | std::ios::binary);
186 
187  // EXCEPTION CHECKS
188 
189  if (fin.fail())
190  {
191  throw std::runtime_error("qpp::load(): Error opening input file \""
192  + std::string(fname) + "\"!");
193  }
194 
195  const std::string header_ = "TYPE::Eigen::Matrix";
196  std::unique_ptr<char[]> fheader_{new char[header_.length()]};
197 
198  // read the header from file
199  fin.read(fheader_.get(), header_.length());
200  if (std::string(fheader_.get(), header_.length()) != header_)
201  {
202  throw std::runtime_error(
203  "qpp::load(): Input file \"" + std::string(fname)
204  + "\" is corrupted!");
205  }
206  // END EXCEPTION CHECKS
207 
208  idx rows, cols;
209  fin.read(reinterpret_cast<char*>(&rows), sizeof(rows));
210  fin.read(reinterpret_cast<char*>(&cols), sizeof(cols));
211 
212  dyn_mat<typename Derived::Scalar> A(rows, cols);
213 
214  fin.read(reinterpret_cast<char*>(A.data()),
215  sizeof(typename Derived::Scalar) * rows * cols);
216 
217  fin.close();
218 
219  return A;
220 }
221 
222 } /* namespace qpp */
223 
224 #endif /* INPUT_OUTPUT_H_ */
bool check_nonzero_size(const T &x) noexcept
Definition: util.h:129
constexpr double chop
Used in qpp::disp() for setting to zero numbers that have their absolute value smaller than qpp::chop...
Definition: constants.h:56
Eigen::Matrix< Scalar, Eigen::Dynamic, Eigen::Dynamic > dyn_mat
Dynamic Eigen matrix over the field specified by Scalar.
Definition: types.h:77
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:63
Definition: iomanip.h:128
std::complex< double > cplx
Complex number in double precision.
Definition: types.h:45
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:182
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:128
std::size_t idx
Non-negative integer index.
Definition: types.h:35
internal::IOManipEigen disp(const Eigen::MatrixBase< Derived > &A, double chop=qpp::chop)
Eigen expression ostream manipulator.
Definition: input_output.h:40
Object has zero size exception.
Definition: exception.h:134