Quantum++  v1.2
A modern C++11 quantum computing library
input_output.h
Go to the documentation of this file.
1 /*
2  * This file is part of Quantum++.
3  *
4  * MIT License
5  *
6  * Copyright (c) 2013 - 2019 Vlad Gheorghiu (vgheorgh@gmail.com)
7  *
8  * Permission is hereby granted, free of charge, to any person obtaining a copy
9  * of this software and associated documentation files (the "Software"), to deal
10  * in the Software without restriction, including without limitation the rights
11  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12  * copies of the Software, and to permit persons to whom the Software is
13  * furnished to do so, subject to the following conditions:
14  *
15  * The above copyright notice and this permission notice shall be included in
16  * all copies or substantial portions of the Software.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24  * SOFTWARE.
25  */
26 
32 #ifndef INPUT_OUTPUT_H_
33 #define INPUT_OUTPUT_H_
34 
35 namespace qpp {
43 template <typename Derived>
44 internal::IOManipEigen disp(const Eigen::MatrixBase<Derived>& A,
45  double chop = qpp::chop) {
46  return internal::IOManipEigen(A, chop);
47 }
48 
58  return internal::IOManipEigen(z, chop);
59 }
60 
71 template <typename InputIterator>
72 internal::IOManipRange<InputIterator>
73 disp(InputIterator first, InputIterator last, const std::string& separator,
74  const std::string& start = "[", const std::string& end = "]") {
75  return internal::IOManipRange<InputIterator>(first, last, separator, start,
76  end);
77 }
78 
89 template <typename Container>
90 internal::IOManipRange<typename Container::const_iterator>
91 disp(const Container& c, const std::string& separator,
92  const std::string& start = "[", const std::string& end = "]",
93  typename std::enable_if<is_iterable<Container>::value>::type* = nullptr) {
95  std::begin(c), std::end(c), separator, start, end);
96 }
97 
108 template <typename PointerType>
109 internal::IOManipPointer<PointerType>
110 disp(const PointerType* p, idx N, const std::string& separator,
111  const std::string& start = "[", const std::string& end = "]") {
112  return internal::IOManipPointer<PointerType>(p, N, separator, start, end);
113 }
114 
123 template <typename Derived>
124 void save(const Eigen::MatrixBase<Derived>& A, const std::string& fname) {
125  const dyn_mat<typename Derived::Scalar>& rA = A.derived();
126 
127  // EXCEPTION CHECKS
128 
129  // check zero-size
131  throw exception::ZeroSize("qpp::save()");
132 
133  std::fstream fout;
134  fout.open(fname, std::ios::out | std::ios::binary);
135 
136  if (fout.fail()) {
137  throw std::runtime_error("qpp::save(): Error writing output file \"" +
138  std::string(fname) + "\"!");
139  }
140  // END EXCEPTION CHECKS
141 
142  // write the header to file
143  const std::string header_ = "TYPE::Eigen::Matrix";
144  fout.write(header_.c_str(), header_.length());
145 
146  idx rows = static_cast<idx>(rA.rows());
147  idx cols = static_cast<idx>(rA.cols());
148  fout.write(reinterpret_cast<const char*>(&rows), sizeof(rows));
149  fout.write(reinterpret_cast<const char*>(&cols), sizeof(cols));
150 
151  fout.write(reinterpret_cast<const char*>(rA.data()),
152  sizeof(typename Derived::Scalar) * rows * cols);
153 
154  fout.close();
155 }
156 
174 template <typename Derived>
175 dyn_mat<typename Derived::Scalar> load(const std::string& fname) {
176  std::fstream fin;
177  fin.open(fname, std::ios::in | std::ios::binary);
178 
179  // EXCEPTION CHECKS
180 
181  if (fin.fail()) {
182  throw std::runtime_error("qpp::load(): Error opening input file \"" +
183  std::string(fname) + "\"!");
184  }
185 
186  const std::string header_ = "TYPE::Eigen::Matrix";
187  std::unique_ptr<char[]> fheader_{new char[header_.length()]};
188 
189  // read the header from file
190  fin.read(fheader_.get(), header_.length());
191  if (std::string(fheader_.get(), header_.length()) != header_) {
192  throw std::runtime_error("qpp::load(): Input file \"" +
193  std::string(fname) + "\" is corrupted!");
194  }
195  // END EXCEPTION CHECKS
196 
197  idx rows, cols;
198  fin.read(reinterpret_cast<char*>(&rows), sizeof(rows));
199  fin.read(reinterpret_cast<char*>(&cols), sizeof(cols));
200 
201  dyn_mat<typename Derived::Scalar> A(rows, cols);
202 
203  fin.read(reinterpret_cast<char*>(A.data()),
204  sizeof(typename Derived::Scalar) * rows * cols);
205 
206  fin.close();
207 
208  return A;
209 }
210 
211 } /* namespace qpp */
212 
213 #endif /* INPUT_OUTPUT_H_ */
bool check_nonzero_size(const T &x) noexcept
Definition: util.h:123
constexpr double chop
Used in qpp::disp() for setting to zero numbers that have their absolute value smaller than qpp::chop...
Definition: constants.h:60
Eigen::Matrix< Scalar, Eigen::Dynamic, Eigen::Dynamic > dyn_mat
Dynamic Eigen matrix over the field specified by Scalar.
Definition: types.h:81
Definition: iomanip.h:41
Quantum++ main namespace.
Definition: circuits.h:35
Checks whether T is compatible with an STL-like iterable container.
Definition: traits.h:71
Definition: iomanip.h:117
std::complex< double > cplx
Complex number in double precision.
Definition: types.h:49
Definition: iomanip.h:78
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:175
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:124
std::size_t idx
Non-negative integer index, make sure you use an unsigned type.
Definition: types.h:39
internal::IOManipEigen disp(const Eigen::MatrixBase< Derived > &A, double chop=qpp::chop)
Eigen expression ostream manipulator.
Definition: input_output.h:44
Object has zero size exception.
Definition: exception.h:134