8#ifndef IGL_MATLAB_MATLAB_WORKSPACE_H
9#define IGL_MATLAB_MATLAB_WORKSPACE_H
12#include <Eigen/Sparse>
39 std::vector<std::string> names;
41 std::vector<mxArray*> data;
51 inline bool write(
const std::string & path)
const;
56 inline bool read(
const std::string & path);
65 template <
typename DerivedM>
67 const Eigen::PlainObjectBase<DerivedM>& M,
68 const std::string & name);
71 template <
typename MT>
73 const Eigen::SparseMatrix<MT>& M,
74 const std::string & name);
77 template <
typename ScalarM>
79 const std::vector<std::vector<ScalarM> > & vM,
80 const std::string & name);
83 template <
typename ScalarV>
85 const std::vector<ScalarV> & vV,
86 const std::string & name);
94 const Eigen::Quaternion<Q> & q,
95 const std::string & name);
99 const std::string & name);
103 template <
typename DerivedM>
105 const Eigen::DenseBase<DerivedM>& M,
106 const std::string & name);
109 template <
typename ScalarM>
111 const std::vector<std::vector<ScalarM> > & vM,
112 const std::string & name);
115 template <
typename ScalarV>
117 const std::vector<ScalarV> & vV,
118 const std::string & name);
127 template <
typename DerivedM>
129 const std::string & name,
130 Eigen::PlainObjectBase<DerivedM>& M);
133 template <
typename MT>
135 const std::string & name,
136 Eigen::SparseMatrix<MT>& M);
139 const std::string & name,
143 const std::string & name,
149 template <
typename DerivedM>
151 const std::string & name,
152 Eigen::PlainObjectBase<DerivedM>& M);
187 for_each(data.begin(),data.end(),&mxDestroyArray);
195 MATFile * mat_file = matOpen(path.c_str(),
"w");
198 fprintf(stderr,
"Error opening file %s\n",path.c_str());
201 assert(names.size() == data.size());
203 for(
int i = 0;i < (int)names.size(); i++)
206 int status = matPutVariable(mat_file,names[i].c_str(), data[i]);
209 cerr<<
"^MatlabWorkspace::save Error: matPutVariable ("<<names[i]<<
214 if(matClose(mat_file) != 0)
216 fprintf(stderr,
"Error closing file %s\n",path.c_str());
228 mat_file = matOpen(path.c_str(),
"r");
229 if (mat_file == NULL)
231 cerr<<
"Error: failed to open "<<path<<endl;
236 const char ** dir = (
const char **)matGetDir(mat_file, &ndir);
238 cerr<<
"Error reading directory of file "<< path<<endl;
244 if(matClose(mat_file) != 0)
246 cerr<<
"Error: failed to close file "<<path<<endl;
249 mat_file = matOpen(path.c_str(),
"r");
250 if (mat_file == NULL)
252 cerr<<
"Error: failed to open "<<path<<endl;
258 for (
int i=0; i<ndir; i++)
261 mxArray * mx_data = matGetNextVariable(mat_file, &name);
264 cerr<<
"Error: matGetNextVariable failed in "<<path<<endl;
267 const int dims = mxGetNumberOfDimensions(mx_data);
271 fprintf(stderr,
"Variable '%s' has %d ≠ 2 dimensions. Skipping\n",
273 mxDestroyArray(mx_data);
277 names.push_back(name);
278 data.push_back(mx_data);
281 if(matClose(mat_file) != 0)
283 cerr<<
"Error: failed to close file "<<path<<endl;
291template <
typename DerivedM>
293 const Eigen::PlainObjectBase<DerivedM>& M,
294 const std::string & name)
297 const int m = M.rows();
298 const int n = M.cols();
299 mxArray * mx_data = mxCreateDoubleMatrix(m,n,mxREAL);
300 data.push_back(mx_data);
301 names.push_back(name);
304 Eigen::Map< Eigen::Matrix<double,Eigen::Dynamic,Eigen::Dynamic> >
305 map(mxGetPr(mx_data),m,n);
306 map = M.template cast<double>();
311template <
typename MT>
313 const Eigen::SparseMatrix<MT>& M,
314 const std::string & name)
317 const int m = M.rows();
318 const int n = M.cols();
320 assert(n==M.outerSize());
321 const int nzmax = M.nonZeros();
322 mxArray * mx_data = mxCreateSparse(m, n, nzmax, mxREAL);
323 data.push_back(mx_data);
324 names.push_back(name);
326 double * pr = mxGetPr(mx_data);
327 mwIndex * ir = mxGetIr(mx_data);
328 mwIndex * jc = mxGetJc(mx_data);
332 for(
int j=0; j<M.outerSize();j++)
336 for(
typename Eigen::SparseMatrix<MT>::InnerIterator it (M,j); it; ++it)
343 jc[M.outerSize()] = k;
348template <
typename ScalarM>
350 const std::vector<std::vector<ScalarM> > & vM,
351 const std::string & name)
355 return this->save(M,name);
358template <
typename ScalarV>
360 const std::vector<ScalarV> & vV,
361 const std::string & name)
365 return this->save(V,name);
370 const Eigen::Quaternion<Q> & q,
371 const std::string & name)
373 Eigen::Matrix<Q,1,4> qm;
378 return save(qm,name);
383 const std::string & name)
385 Eigen::VectorXd v(1);
390template <
typename DerivedM>
393 const Eigen::DenseBase<DerivedM>& M,
394 const std::string & name)
398 return this->save(Mp1,name);
401template <
typename ScalarM>
403 const std::vector<std::vector<ScalarM> > & vM,
404 const std::string & name)
408 return this->save_index(M,name);
411template <
typename ScalarV>
413 const std::vector<ScalarV> & vV,
414 const std::string & name)
418 return this->save_index(V,name);
421template <
typename DerivedM>
423 const std::string & name,
424 Eigen::PlainObjectBase<DerivedM>& M)
427 const int i = std::find(names.begin(), names.end(), name)-names.begin();
428 if(i>=(
int)names.size())
432 assert(i<=(
int)data.size());
433 mxArray * mx_data = data[i];
434 assert(!mxIsSparse(mx_data));
435 assert(mxGetNumberOfDimensions(mx_data) == 2);
437 const int m = mxGetM(mx_data);
438 const int n = mxGetN(mx_data);
441 if(DerivedM::IsVectorAtCompileTime)
443 assert(m==1 || n==1 || (m==0 && n==0));
449 assert(mxGetNumberOfElements(mx_data) == M.size());
451 M = Eigen::Map< Eigen::Matrix<double,Eigen::Dynamic,Eigen::Dynamic> >
452 (mxGetPr(mx_data),M.rows(),M.cols()).cast<typename DerivedM::Scalar>();
456template <
typename MT>
458 const std::string & name,
459 Eigen::SparseMatrix<MT>& M)
462 using namespace Eigen;
463 const int i = std::find(names.begin(), names.end(), name)-names.begin();
464 if(i>=(
int)names.size())
468 assert(i<=(
int)data.size());
469 mxArray * mx_data = data[i];
471 if(mxGetNumberOfElements(mx_data) == 0)
476 assert(mxIsSparse(mx_data));
477 assert(mxGetNumberOfDimensions(mx_data) == 2);
479 const int m = mxGetM(mx_data);
480 const int n = mxGetN(mx_data);
484 double * pr = mxGetPr(mx_data);
485 mwIndex * ir = mxGetIr(mx_data);
486 mwIndex * jc = mxGetJc(mx_data);
487 vector<Triplet<MT> > MIJV;
488 const int nnz = mxGetNzmax(mx_data);
492 for(
int j=0; j<n;j++)
495 while(k<(
int)jc[j+1])
498 assert((
int)ir[k]<m);
500 MIJV.push_back(Triplet<MT >(ir[k],j,pr[k]));
505 M.setFromTriplets(MIJV.begin(),MIJV.end());
511 const std::string & name,
515 const int i = std::find(names.begin(), names.end(), name)-names.begin();
516 if(i>=(
int)names.size())
520 assert(i<=(
int)data.size());
521 mxArray * mx_data = data[i];
522 assert(!mxIsSparse(mx_data));
523 assert(mxGetNumberOfDimensions(mx_data) == 2);
525 assert(mxGetNumberOfElements(mx_data) == 1);
528 mxGetPr(mx_data)+mxGetNumberOfElements(mx_data),
534 const std::string & name,
538 const int i = std::find(names.begin(), names.end(), name)-names.begin();
539 if(i>=(
int)names.size())
543 assert(i<=(
int)data.size());
544 mxArray * mx_data = data[i];
545 assert(!mxIsSparse(mx_data));
546 assert(mxGetNumberOfDimensions(mx_data) == 2);
548 assert(mxGetNumberOfElements(mx_data) == 1);
551 mxGetPr(mx_data)+mxGetNumberOfElements(mx_data),
556template <
typename DerivedM>
558 const std::string & name,
559 Eigen::PlainObjectBase<DerivedM>& M)
Class which contains data of a matlab workspace which can be written to a .mat file and loaded from m...
Definition MatlabWorkspace.h:35
MatlabWorkspace & save_index(const Eigen::DenseBase< DerivedM > &M, const std::string &name)
Same as save() but adds 1 to each element, useful for saving "index" matrices like lists of faces or ...
MatlabWorkspace & save(const Eigen::PlainObjectBase< DerivedM > &M, const std::string &name)
Assign data to a variable name in the workspace.
MatlabWorkspace & save(const std::vector< std::vector< ScalarM > > &vM, const std::string &name)
This is an overloaded member function, provided for convenience. It differs from the above function o...
MatlabWorkspace & save_index(const std::vector< ScalarV > &vV, const std::string &name)
This is an overloaded member function, provided for convenience. It differs from the above function o...
bool write(const std::string &path) const
Save current list of variables.
Definition MatlabWorkspace.h:192
bool find(const std::string &name, Eigen::PlainObjectBase< DerivedM > &M)
Find a certain matrix by name.
Definition MatlabWorkspace.h:422
MatlabWorkspace & save(const std::vector< ScalarV > &vV, const std::string &name)
This is an overloaded member function, provided for convenience. It differs from the above function o...
bool read(const std::string &path)
Load list of variables from .mat file.
Definition MatlabWorkspace.h:222
MatlabWorkspace()
Definition MatlabWorkspace.h:173
MatlabWorkspace & save(const Eigen::SparseMatrix< MT > &M, const std::string &name)
This is an overloaded member function, provided for convenience. It differs from the above function o...
~MatlabWorkspace()
Definition MatlabWorkspace.h:179
bool find_index(const std::string &name, Eigen::PlainObjectBase< DerivedM > &M)
Subtracts 1 from all entries.
Definition MatlabWorkspace.h:557
MatlabWorkspace & save_index(const std::vector< std::vector< ScalarM > > &vM, const std::string &name)
This is an overloaded member function, provided for convenience. It differs from the above function o...
MatlabWorkspace & save(const Eigen::Quaternion< Q > &q, const std::string &name)
void clear()
Clear names and data of variables in workspace.
Definition MatlabWorkspace.h:185
void for_each(const Eigen::SparseMatrix< AType > &A, const Func &func)
FOR_EACH Call a given function for each non-zero (i.e., explicit value might actually be ==0) in a Sp...
Definition for_each.h:31
bool list_to_matrix(const std::vector< std::vector< T > > &V, Eigen::PlainObjectBase< Derived > &M)
Convert a list (std::vector) of row vectors of the same length to a matrix.
void find(const Eigen::SparseMatrix< T > &X, Eigen::DenseBase< DerivedI > &I, Eigen::DenseBase< DerivedJ > &J, Eigen::DenseBase< DerivedV > &V)
Find the non-zero entries and there respective indices in a sparse matrix.