Quantum++  v0.8
C++11 quantum computing library
matlab.h
Go to the documentation of this file.
1 /*
2  * Quantum++
3  *
4  * Copyright (c) 2013 - 2015 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 MATLAB_MATLAB_H_
28 #define MATLAB_MATLAB_H_
29 
30 // MATLAB I/O interfacing
31 // add the path to $MATLAB_INSTALLATION_FOLDER/extern/include in include path
32 
33 #include "mat.h" // path to this file is defined in the Makefile
34 #include "mex.h" // path to this file is defined in the Makefile
35 
36 namespace qpp
37 {
38 
47 template<typename Derived>
48 Derived loadMATLABmatrix(const std::string& mat_file,
49  const std::string& var_name)
50 {
51  throw Exception("qpp::loadMATLABmatrix()",
53 }
54 
78 template<>
79 inline dmat loadMATLABmatrix(const std::string& mat_file,
80  const std::string& var_name)
81 {
82  MATFile* pmat = matOpen(mat_file.c_str(), "r");
83  if (!pmat)
84  {
85  throw std::runtime_error(
86  "qpp::loadMATLABmatrix(): Can not open MATLAB file "
87  + mat_file + "!");
88  }
89 
90  mxArray* pa = matGetVariable(pmat, var_name.c_str());
91  if (!pa)
92  throw std::runtime_error(
93  "qpp::loadMATLABmatrix(): Can not load the variable "
94  + var_name + " from MATLAB file " + mat_file + "!");
95 
96  if (mxGetNumberOfDimensions(pa) != 2) // not a matrix
97  throw std::runtime_error(
98  "qpp::loadMATLABmatrix(): Loaded variable " + var_name
99  + " is not 2-dimensional!");
100 
101  if (!mxIsDouble(pa))
102  throw std::runtime_error(
103  "qpp::loadMATLABmatrix(): Loaded variable " + var_name
104  + " is not in double-precision format!");
105 
106  idx rows = mxGetM(pa);
107  idx cols = mxGetN(pa);
108 
109  dmat result(rows, cols);
110 
111  std::memcpy(result.data(), mxGetPr(pa),
112  sizeof(double) * mxGetNumberOfElements(pa));
113 
114  mxDestroyArray(pa);
115  matClose(pmat);
116 
117  return result;
118 }
119 
140 template<>
141 inline cmat loadMATLABmatrix(const std::string& mat_file,
142  const std::string& var_name)
143 {
144  MATFile* pmat = matOpen(mat_file.c_str(), "r");
145  if (!pmat)
146  {
147  throw std::runtime_error(
148  "qpp::loadMATLABmatrix(): Can not open MATLAB file "
149  + mat_file + "!");
150  }
151 
152  mxArray* pa = matGetVariable(pmat, var_name.c_str());
153  if (!pa)
154  throw std::runtime_error(
155  "qpp::loadMATLABmatrix(): Can not load the variable "
156  + var_name + " from MATLAB file " + mat_file + "!");
157 
158  if (mxGetNumberOfDimensions(pa) != 2) // not a matrix
159  throw std::runtime_error(
160  "qpp::loadMATLABmatrix(): Loaded variable " + var_name
161  + " is not 2-dimensional!");
162 
163  if (!mxIsDouble(pa))
164  throw std::runtime_error(
165  "qpp::loadMATLABmatrix(): Loaded variable " + var_name
166  + " is not in double-precision format!");
167 
168  idx rows = mxGetM(pa);
169  idx cols = mxGetN(pa);
170 
171  dmat result_re(rows, cols);
172  dmat result_im(rows, cols);
173 
174  // real part and imaginary part pointers
175  double* pa_re = nullptr, * pa_im = nullptr;
176 
177  // Populate the real part of the created array.
178  pa_re = static_cast<double*>(mxGetPr(pa));
179  std::memcpy(result_re.data(), pa_re,
180  sizeof(double) * mxGetNumberOfElements(pa));
181 
182  if (mxIsComplex(pa)) // populate the imaginary part if exists
183  {
184  pa_im = static_cast<double*>(mxGetPi(pa));
185  std::memcpy(result_im.data(), pa_im,
186  sizeof(double) * mxGetNumberOfElements(pa));
187  }
188  else // set to zero the imaginary part
189  {
190  std::memset(result_im.data(), 0,
191  sizeof(double) * mxGetNumberOfElements(pa));
192  }
193 
194  mxDestroyArray(pa);
195  matClose(pmat);
196 
197  return (result_re.cast<cplx>()) + 1_i * (result_im.cast<cplx>());
198 }
199 
208 template<typename Derived>
209 void saveMATLABmatrix(const Eigen::MatrixBase <Derived>& A,
210  const std::string& mat_file, const std::string& var_name,
211  const std::string& mode)
212 {
213  throw Exception("qpp::saveMATLABmatrix()",
215 }
216 
229 template<>
230 // Eigen::MatrixXd specialization
231 inline void saveMATLABmatrix(const Eigen::MatrixBase <dmat>& A,
232  const std::string& mat_file,
233  const std::string& var_name,
234  const std::string& mode)
235 {
236  const dmat& rA = A;
237 
238  // check zero-size
240  throw Exception("qpp::saveMATLABmatrix()", Exception::Type::ZERO_SIZE);
241 
242  MATFile* pmat = matOpen(mat_file.c_str(), mode.c_str());
243  if (!pmat)
244  throw std::runtime_error(
245  "qpp::saveMATLABmatrix(): Can not open/create MATLAB file "
246  + mat_file + "!");
247 
248  mxArray* pa = mxCreateDoubleMatrix(rA.rows(), rA.cols(), mxREAL);
249  if (!pa)
250  throw std::runtime_error(
251  "qpp::saveMATLABmatrix(): mxCreateDoubleMatrix failed!");
252 
253  std::memcpy(mxGetPr(pa), rA.data(), sizeof(double) * rA.size());
254 
255  if (matPutVariable(pmat, var_name.c_str(), pa))
256  throw std::runtime_error(
257  "qpp::saveMATLABmatrix(): Can not write the variable "
258  + var_name + " to MATLAB file " + mat_file + "!");
259 
260  mxDestroyArray(pa);
261  matClose(pmat);
262 }
263 
276 template<>
277 // Eigen::MatrixXcd specialization
278 inline void saveMATLABmatrix(const Eigen::MatrixBase <cmat>& A,
279  const std::string& mat_file,
280  const std::string& var_name,
281  const std::string& mode)
282 {
283  const cmat& rA = A;
284 
285  // check zero-size
287  throw Exception("qpp::saveMATLABmatrix()", Exception::Type::ZERO_SIZE);
288 
289  // cast the input to a double (internal MATLAB format)
290  dmat tmp_re = rA.real();
291  dmat tmp_im = rA.imag();
292 
293  MATFile* pmat = matOpen(mat_file.c_str(), mode.c_str());
294  if (!pmat)
295  throw std::runtime_error(
296  "qpp::saveMATLABmatrix(): Can not open/create MATLAB file "
297  + mat_file + "!");
298 
299  mxArray* pa = mxCreateDoubleMatrix(
300  tmp_re.rows(), tmp_re.cols(), mxCOMPLEX);
301  if (!pa)
302  throw std::runtime_error(
303  "qpp::saveMATLABmatrix(): mxCreateDoubleMatrix failed!");
304 
305  double* pa_re, * pa_im;
306 
307  /* Populate the real part of the created array. */
308  pa_re = static_cast<double*>(mxGetPr(pa));
309  std::memcpy(pa_re, tmp_re.data(), sizeof(double) * tmp_re.size());
310 
311  /* Populate the imaginary part of the created array. */
312  pa_im = static_cast<double*>(mxGetPi(pa));
313  std::memcpy(pa_im, tmp_im.data(), sizeof(double) * tmp_im.size());
314 
315  if (matPutVariable(pmat, var_name.c_str(), pa))
316  throw std::runtime_error(
317  "qpp::saveMATLABmatrix(): Can not write the variable "
318  + var_name + " to MATLAB file " + mat_file + "!");
319 
320  mxDestroyArray(pa);
321  matClose(pmat);
322 }
323 
324 } /* namespace qpp */
325 #endif /* MATLAB_MATLAB_H_ */
Eigen::MatrixXd dmat
Real (double precision) dynamic Eigen matrix.
Definition: types.h:72
Quantum++ main namespace.
Definition: codes.h:30
std::complex< double > cplx
Complex number in double precision.
Definition: types.h:52
Generates custom exceptions, used when validating function parameters.
Definition: exception.h:39
bool _check_nonzero_size(const T &x) noexcept
Definition: util.h:113
Derived loadMATLABmatrix(const std::string &mat_file, const std::string &var_name)
Loads an Eigen dynamic matrix from a MATLAB .mat file, generic version.
Definition: matlab.h:48
Eigen::MatrixXcd cmat
Complex (double precision) dynamic Eigen matrix.
Definition: types.h:67
void saveMATLABmatrix(const Eigen::MatrixBase< Derived > &A, const std::string &mat_file, const std::string &var_name, const std::string &mode)
Saves an Eigen dynamic matrix to a MATLAB .mat file, generic version.
Definition: matlab.h:209
std::size_t idx
Non-negative integer index.
Definition: types.h:36