XACC
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 - 2020 Vlad Gheorghiu.
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 
57 inline internal::IOManipEigen disp(cplx z, double chop = qpp::chop) {
58  return internal::IOManipEigen(z, chop);
59 }
60 
72 template <typename InputIterator>
73 internal::IOManipRange<InputIterator>
74 disp(InputIterator first, InputIterator last, const std::string& separator,
75  const std::string& start = "[", const std::string& end = "]",
76  double chop = qpp::chop) {
77  return internal::IOManipRange<InputIterator>(first, last, separator, start,
78  end, chop);
79 }
80 
92 template <typename Container>
93 internal::IOManipRange<typename Container::const_iterator>
94 disp(const Container& c, const std::string& separator,
95  const std::string& start = "[", const std::string& end = "]",
96  double chop = qpp::chop,
97  typename std::enable_if<is_iterable<Container>::value>::type* = nullptr) {
98  return internal::IOManipRange<typename Container::const_iterator>(
99  std::begin(c), std::end(c), separator, start, end, chop);
100 }
101 
113 template <typename PointerType>
114 internal::IOManipPointer<PointerType>
115 disp(const PointerType* p, idx N, const std::string& separator,
116  const std::string& start = "[", const std::string& end = "]",
117  double chop = qpp::chop) {
118  return internal::IOManipPointer<PointerType>(p, N, separator, start, end,
119  chop);
120 }
121 
130 template <typename Derived>
131 void save(const Eigen::MatrixBase<Derived>& A, const std::string& fname) {
132  const dyn_mat<typename Derived::Scalar>& rA = A.derived();
133 
134  // EXCEPTION CHECKS
135 
136  // check zero-size
137  if (!internal::check_nonzero_size(rA))
138  throw exception::ZeroSize("qpp::save()");
139 
140  std::fstream fout;
141  fout.open(fname, std::ios::out | std::ios::binary);
142 
143  if (fout.fail()) {
144  throw std::runtime_error("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 
180 template <typename Derived>
181 dyn_mat<typename Derived::Scalar> load(const std::string& fname) {
182  std::fstream fin;
183  fin.open(fname, std::ios::in | std::ios::binary);
184 
185  // EXCEPTION CHECKS
186 
187  if (fin.fail()) {
188  throw std::runtime_error("qpp::load(): Error opening input file \"" +
189  std::string(fname) + "\"!");
190  }
191 
192  const std::string header_ = "TYPE::Eigen::Matrix";
193  std::unique_ptr<char[]> fheader_{new char[header_.length()]};
194 
195  // read the header from file
196  fin.read(fheader_.get(), header_.length());
197  if (std::string(fheader_.get(), header_.length()) != header_) {
198  throw std::runtime_error("qpp::load(): Input file \"" +
199  std::string(fname) + "\" is corrupted!");
200  }
201  // END EXCEPTION CHECKS
202 
203  idx rows, cols;
204  fin.read(reinterpret_cast<char*>(&rows), sizeof(rows));
205  fin.read(reinterpret_cast<char*>(&cols), sizeof(cols));
206 
207  dyn_mat<typename Derived::Scalar> A(rows, cols);
208 
209  fin.read(reinterpret_cast<char*>(A.data()),
210  sizeof(typename Derived::Scalar) * rows * cols);
211 
212  fin.close();
213 
214  return A;
215 }
216 
217 } /* namespace qpp */
218 
219 #endif /* INPUT_OUTPUT_H_ */
Quantum++ main namespace.
Definition: circuits.h:35