MueLu  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
MueLu_MatlabUtils.cpp
Go to the documentation of this file.
1 // @HEADER
2 // *****************************************************************************
3 // MueLu: A package for multigrid based preconditioning
4 //
5 // Copyright 2012 NTESS and the MueLu contributors.
6 // SPDX-License-Identifier: BSD-3-Clause
7 // *****************************************************************************
8 // @HEADER
9 
11 
12 #if !defined(HAVE_MUELU_MATLAB) || !defined(HAVE_MUELU_EPETRA)
13 #error "Muemex types require MATLAB, Epetra and Tpetra."
14 #else
15 
16 /* Stuff for MATLAB R2006b vs. previous versions */
17 #if (defined(MX_API_VER) && MX_API_VER >= 0x07030000)
18 #else
19 typedef int mwIndex;
20 #endif
21 
22 using namespace std;
23 using namespace Teuchos;
24 
25 namespace MueLu {
26 
27 /* Explicit instantiation of MuemexData variants */
28 template class MuemexData<RCP<Xpetra::MultiVector<double, mm_LocalOrd, mm_GlobalOrd, mm_node_t> > >;
29 template class MuemexData<RCP<Xpetra::MultiVector<complex_t, mm_LocalOrd, mm_GlobalOrd, mm_node_t> > >;
30 template class MuemexData<RCP<Xpetra::Matrix<double, mm_LocalOrd, mm_GlobalOrd, mm_node_t> > >;
31 template class MuemexData<RCP<Xpetra::Matrix<complex_t, mm_LocalOrd, mm_GlobalOrd, mm_node_t> > >;
32 template class MuemexData<RCP<MAggregates> >;
33 template class MuemexData<RCP<MAmalInfo> >;
34 template class MuemexData<int>;
35 template class MuemexData<bool>;
36 template class MuemexData<complex_t>;
37 template class MuemexData<string>;
38 template class MuemexData<double>;
39 template class MuemexData<RCP<Tpetra::CrsMatrix<double, mm_LocalOrd, mm_GlobalOrd, mm_node_t> > >;
40 template class MuemexData<RCP<Tpetra::CrsMatrix<complex_t, mm_LocalOrd, mm_GlobalOrd, mm_node_t> > >;
41 template class MuemexData<RCP<Epetra_MultiVector> >;
42 template class MuemexData<RCP<Tpetra::MultiVector<double, mm_LocalOrd, mm_GlobalOrd, mm_node_t> > >;
43 template class MuemexData<RCP<Tpetra::MultiVector<complex_t, mm_LocalOrd, mm_GlobalOrd, mm_node_t> > >;
44 template class MuemexData<RCP<Xpetra::Vector<mm_LocalOrd, mm_LocalOrd, mm_GlobalOrd, mm_node_t> > >;
45 
46 // Flag set to true if MATLAB's CSC matrix index type is not int (usually false)
47 bool rewrap_ints = sizeof(int) != sizeof(mwIndex);
48 
49 int* mwIndex_to_int(int N, mwIndex* mwi_array) {
50  // int* rv = (int*) malloc(N * sizeof(int));
51  int* rv = new int[N]; // not really better but may avoid confusion for valgrind
52  for (int i = 0; i < N; i++)
53  rv[i] = (int)mwi_array[i];
54  return rv;
55 }
56 
57 /* ******************************* */
58 /* Specializations */
59 /* ******************************* */
60 
61 template <>
62 mxArray* createMatlabSparse<double>(int numRows, int numCols, int nnz) {
63  return mxCreateSparse(numRows, numCols, nnz, mxREAL);
64 }
65 
66 template <>
67 mxArray* createMatlabSparse<complex_t>(int numRows, int numCols, int nnz) {
68  return mxCreateSparse(numRows, numCols, nnz, mxCOMPLEX);
69 }
70 
71 template <>
72 void fillMatlabArray<double>(double* array, const mxArray* mxa, int n) {
73  memcpy(mxGetPr(mxa), array, n * sizeof(double));
74 }
75 
76 template <>
77 void fillMatlabArray<complex_t>(complex_t* array, const mxArray* mxa, int n) {
78  double* pr = mxGetPr(mxa);
79  double* pi = mxGetPi(mxa);
80  for (int i = 0; i < n; i++) {
81  pr[i] = std::real<double>(array[i]);
82  pi[i] = std::imag<double>(array[i]);
83  }
84 }
85 
86 /******************************/
87 /* Callback Functions */
88 /******************************/
89 
90 void callMatlabNoArgs(std::string function) {
91  int result = mexEvalString(function.c_str());
92  if (result != 0)
93  mexPrintf("An error occurred while running a MATLAB command.");
94 }
95 
96 std::vector<RCP<MuemexArg> > callMatlab(std::string function, int numOutputs, std::vector<RCP<MuemexArg> > args) {
97  using Teuchos::rcp_static_cast;
98  mxArray** matlabArgs = new mxArray*[args.size()];
99  mxArray** matlabOutput = new mxArray*[numOutputs];
100  std::vector<RCP<MuemexArg> > output;
101 
102  for (int i = 0; i < int(args.size()); i++) {
103  try {
104  switch (args[i]->type) {
105  case BOOL:
106  matlabArgs[i] = rcp_static_cast<MuemexData<bool>, MuemexArg>(args[i])->convertToMatlab();
107  break;
108  case INT:
109  matlabArgs[i] = rcp_static_cast<MuemexData<int>, MuemexArg>(args[i])->convertToMatlab();
110  break;
111  case DOUBLE:
112  matlabArgs[i] = rcp_static_cast<MuemexData<double>, MuemexArg>(args[i])->convertToMatlab();
113  break;
114  case STRING:
115  matlabArgs[i] = rcp_static_cast<MuemexData<std::string>, MuemexArg>(args[i])->convertToMatlab();
116  break;
117  case COMPLEX:
118  matlabArgs[i] = rcp_static_cast<MuemexData<complex_t>, MuemexArg>(args[i])->convertToMatlab();
119  break;
120  case XPETRA_MAP:
121  matlabArgs[i] = rcp_static_cast<MuemexData<RCP<Xpetra_map> >, MuemexArg>(args[i])->convertToMatlab();
122  break;
124  matlabArgs[i] = rcp_static_cast<MuemexData<RCP<Xpetra_ordinal_vector> >, MuemexArg>(args[i])->convertToMatlab();
125  break;
127  matlabArgs[i] = rcp_static_cast<MuemexData<RCP<Tpetra::MultiVector<double, mm_LocalOrd, mm_GlobalOrd, mm_node_t> > >, MuemexArg>(args[i])->convertToMatlab();
128  break;
130  matlabArgs[i] = rcp_static_cast<MuemexData<RCP<Tpetra::MultiVector<complex_t, mm_LocalOrd, mm_GlobalOrd, mm_node_t> > >, MuemexArg>(args[i])->convertToMatlab();
131  break;
133  matlabArgs[i] = rcp_static_cast<MuemexData<RCP<Tpetra::CrsMatrix<double, mm_LocalOrd, mm_GlobalOrd, mm_node_t> > >, MuemexArg>(args[i])->convertToMatlab();
134  break;
136  matlabArgs[i] = rcp_static_cast<MuemexData<RCP<Tpetra::CrsMatrix<complex_t, mm_LocalOrd, mm_GlobalOrd, mm_node_t> > >, MuemexArg>(args[i])->convertToMatlab();
137  break;
139  matlabArgs[i] = rcp_static_cast<MuemexData<RCP<Xpetra_Matrix_double> >, MuemexArg>(args[i])->convertToMatlab();
140  break;
142  matlabArgs[i] = rcp_static_cast<MuemexData<RCP<Xpetra_Matrix_complex> >, MuemexArg>(args[i])->convertToMatlab();
143  break;
145  matlabArgs[i] = rcp_static_cast<MuemexData<RCP<Xpetra_MultiVector_double> >, MuemexArg>(args[i])->convertToMatlab();
146  break;
148  matlabArgs[i] = rcp_static_cast<MuemexData<RCP<Xpetra_MultiVector_complex> >, MuemexArg>(args[i])->convertToMatlab();
149  break;
150  case EPETRA_CRSMATRIX:
151  matlabArgs[i] = rcp_static_cast<MuemexData<RCP<Epetra_CrsMatrix> >, MuemexArg>(args[i])->convertToMatlab();
152  break;
153  case EPETRA_MULTIVECTOR:
154  matlabArgs[i] = rcp_static_cast<MuemexData<RCP<Epetra_MultiVector> >, MuemexArg>(args[i])->convertToMatlab();
155  break;
156  case AGGREGATES:
157  matlabArgs[i] = rcp_static_cast<MuemexData<RCP<MAggregates> >, MuemexArg>(args[i])->convertToMatlab();
158  break;
159  case AMALGAMATION_INFO:
160  matlabArgs[i] = rcp_static_cast<MuemexData<RCP<MAmalInfo> >, MuemexArg>(args[i])->convertToMatlab();
161  break;
162  case GRAPH:
163  matlabArgs[i] = rcp_static_cast<MuemexData<RCP<MGraph> >, MuemexArg>(args[i])->convertToMatlab();
164 #ifdef HAVE_MUELU_INTREPID2
165  case FIELDCONTAINER_ORDINAL:
166  matlabArgs[i] = rcp_static_cast<MuemexData<RCP<FieldContainer_ordinal> >, MuemexArg>(args[i])->convertToMatlab();
167  break;
168 #endif
169  }
170  } catch (std::exception& e) {
171  mexPrintf("An error occurred while converting arg #%d to MATLAB:\n", i);
172  std::cout << e.what() << std::endl;
173  mexPrintf("Passing 0 instead.\n");
174  matlabArgs[i] = mxCreateDoubleScalar(0);
175  }
176  }
177  // now matlabArgs is populated with MATLAB data types
178  int result = mexCallMATLAB(numOutputs, matlabOutput, args.size(), matlabArgs, function.c_str());
179  if (result != 0)
180  mexPrintf("Matlab encountered an error while running command through muemexCallbacks.\n");
181  // now, if all went well, matlabOutput contains all the output to return to user
182  for (int i = 0; i < numOutputs; i++) {
183  try {
184  output.push_back(convertMatlabVar(matlabOutput[i]));
185  } catch (std::exception& e) {
186  mexPrintf("An error occurred while converting output #%d from MATLAB:\n", i);
187  std::cout << e.what() << std::endl;
188  }
189  }
190  delete[] matlabOutput;
191  delete[] matlabArgs;
192  return output;
193 }
194 
195 /******************************/
196 /* More utility functions */
197 /******************************/
198 
199 template <>
200 mxArray* createMatlabMultiVector<double>(int numRows, int numCols) {
201  return mxCreateDoubleMatrix(numRows, numCols, mxREAL);
202 }
203 
204 template <>
205 mxArray* createMatlabMultiVector<complex_t>(int numRows, int numCols) {
206  return mxCreateDoubleMatrix(numRows, numCols, mxCOMPLEX);
207 }
208 
209 mxArray* saveAmalInfo(RCP<MAmalInfo>& amalInfo) {
210  throw runtime_error("AmalgamationInfo not supported in MueMex yet.");
211  return mxCreateDoubleScalar(0);
212 }
213 
214 bool isValidMatlabAggregates(const mxArray* mxa) {
215  bool isValidAggregates = true;
216  if (!mxIsStruct(mxa))
217  return false;
218  int numFields = mxGetNumberOfFields(mxa); // check that struct has correct # of fields
219  if (numFields != 5)
220  isValidAggregates = false;
221  if (isValidAggregates) {
222  const char* mem1 = mxGetFieldNameByNumber(mxa, 0);
223  if (mem1 == NULL || strcmp(mem1, "nVertices") != 0)
224  isValidAggregates = false;
225  const char* mem2 = mxGetFieldNameByNumber(mxa, 1);
226  if (mem2 == NULL || strcmp(mem2, "nAggregates") != 0)
227  isValidAggregates = false;
228  const char* mem3 = mxGetFieldNameByNumber(mxa, 2);
229  if (mem3 == NULL || strcmp(mem3, "vertexToAggID") != 0)
230  isValidAggregates = false;
231  const char* mem4 = mxGetFieldNameByNumber(mxa, 3);
232  if (mem3 == NULL || strcmp(mem4, "rootNodes") != 0)
233  isValidAggregates = false;
234  const char* mem5 = mxGetFieldNameByNumber(mxa, 4);
235  if (mem4 == NULL || strcmp(mem5, "aggSizes") != 0)
236  isValidAggregates = false;
237  }
238  return isValidAggregates;
239 }
240 
241 bool isValidMatlabGraph(const mxArray* mxa) {
242  bool isValidGraph = true;
243  if (!mxIsStruct(mxa))
244  return false;
245  int numFields = mxGetNumberOfFields(mxa); // check that struct has correct # of fields
246  if (numFields != 2)
247  isValidGraph = false;
248  if (isValidGraph) {
249  const char* mem1 = mxGetFieldNameByNumber(mxa, 0);
250  if (mem1 == NULL || strcmp(mem1, "edges") != 0)
251  isValidGraph = false;
252  const char* mem2 = mxGetFieldNameByNumber(mxa, 1);
253  if (mem2 == NULL || strcmp(mem2, "boundaryNodes") != 0)
254  isValidGraph = false;
255  }
256  return isValidGraph;
257 }
258 
259 std::vector<std::string> tokenizeList(const std::string& params) {
260  using namespace std;
261  vector<string> rlist;
262  const char* delims = ",";
263  char* copy = (char*)malloc(params.length() + 1);
264  strcpy(copy, params.c_str());
265  char* mark = (char*)strtok(copy, delims);
266  while (mark != NULL) {
267  // Remove leading and trailing whitespace in token
268  char* tail = mark + strlen(mark) - 1;
269  while (*mark == ' ')
270  mark++;
271  while (*tail == ' ' && tail > mark)
272  tail--;
273  tail++;
274  *tail = 0;
275  string tok(mark); // copies the characters to string object
276  rlist.push_back(tok);
277  mark = strtok(NULL, delims);
278  }
279  free(copy);
280  return rlist;
281 }
282 
284  using namespace Teuchos;
285  RCP<ParameterList> validParamList = rcp(new ParameterList());
286  validParamList->set<RCP<const FactoryBase> >("A", Teuchos::null, "Factory for the matrix A.");
287  validParamList->set<RCP<const FactoryBase> >("P", Teuchos::null, "Factory for the prolongator.");
288  validParamList->set<RCP<const FactoryBase> >("R", Teuchos::null, "Factory for the restrictor.");
289  validParamList->set<RCP<const FactoryBase> >("Ptent", Teuchos::null, "Factory for the tentative (unsmoothed) prolongator.");
290  validParamList->set<RCP<const FactoryBase> >("Coordinates", Teuchos::null, "Factory for the node coordinates.");
291  validParamList->set<RCP<const FactoryBase> >("Nullspace", Teuchos::null, "Factory for the nullspace.");
292  validParamList->set<RCP<const FactoryBase> >("Aggregates", Teuchos::null, "Factory for the aggregates.");
293  validParamList->set<RCP<const FactoryBase> >("UnamalgamationInfo", Teuchos::null, "Factory for amalgamation.");
294 #ifdef HAVE_MUELU_INTREPID2
295  validParamList->set<RCP<const FactoryBase> >("pcoarsen: element to node map", Teuchos::null, "Generating factory of the element to node map");
296 #endif
297  return validParamList;
298 }
299 
301  switch (mxGetClassID(mxa)) {
302  case mxCHAR_CLASS:
303  // string
304  return rcp_implicit_cast<MuemexArg>(rcp(new MuemexData<std::string>(mxa)));
305  break;
306  case mxLOGICAL_CLASS:
307  // boolean
308  return rcp_implicit_cast<MuemexArg>(rcp(new MuemexData<bool>(mxa)));
309  break;
310  case mxINT32_CLASS:
311  if (mxGetM(mxa) == 1 && mxGetN(mxa) == 1)
312  // individual integer
313  return rcp_implicit_cast<MuemexArg>(rcp(new MuemexData<int>(mxa)));
314  else if (mxGetM(mxa) != 1 || mxGetN(mxa) != 1)
315  // ordinal vector
316  return rcp_implicit_cast<MuemexArg>(rcp(new MuemexData<RCP<Xpetra_ordinal_vector> >(mxa)));
317  else
318  throw std::runtime_error("Error: Don't know what to do with integer array.\n");
319  break;
320  case mxDOUBLE_CLASS:
321  if (mxGetM(mxa) == 1 && mxGetN(mxa) == 1) {
322  if (mxIsComplex(mxa))
323  // single double (scalar, real)
324  return rcp_implicit_cast<MuemexArg>(rcp(new MuemexData<complex_t>(mxa)));
325  else
326  // single complex scalar
327  return rcp_implicit_cast<MuemexArg>(rcp(new MuemexData<double>(mxa)));
328  } else if (mxIsSparse(mxa)) // use a CRS matrix
329  {
330  // Default to Tpetra matrix for this
331  if (mxIsComplex(mxa))
332  // complex matrix
333  return rcp_implicit_cast<MuemexArg>(rcp(new MuemexData<RCP<Xpetra_Matrix_complex> >(mxa)));
334  else
335  // real-valued matrix
336  return rcp_implicit_cast<MuemexArg>(rcp(new MuemexData<RCP<Xpetra_Matrix_double> >(mxa)));
337  } else {
338  // Default to Xpetra multivector for this case
339  if (mxIsComplex(mxa))
340  return rcp_implicit_cast<MuemexArg>(rcp(new MuemexData<RCP<Xpetra::MultiVector<complex_t, mm_LocalOrd, mm_GlobalOrd, mm_node_t> > >(mxa)));
341  else
342  return rcp_implicit_cast<MuemexArg>(rcp(new MuemexData<RCP<Xpetra::MultiVector<double, mm_LocalOrd, mm_GlobalOrd, mm_node_t> > >(mxa)));
343  }
344  break;
345  case mxSTRUCT_CLASS: {
346  // the only thing that should get here currently is an Aggregates struct or Graph struct
347  // verify that it has the correct fields with the correct types
348  // also assume that aggregates data will not be stored in an array of more than 1 element.
349  if (isValidMatlabAggregates(mxa)) {
350  return rcp_implicit_cast<MuemexArg>(rcp(new MuemexData<RCP<MAggregates> >(mxa)));
351  } else if (isValidMatlabGraph(mxa)) {
352  return rcp_implicit_cast<MuemexArg>(rcp(new MuemexData<RCP<MGraph> >(mxa)));
353  } else {
354  throw runtime_error("Invalid aggregates or graph struct passed in from MATLAB.");
355  return Teuchos::null;
356  }
357  break;
358  }
359  default:
360  throw std::runtime_error("MATLAB returned an unsupported type as a function output.\n");
361  return Teuchos::null;
362  }
363 }
364 
365 /******************************/
366 /* Explicit Instantiations */
367 /******************************/
368 
369 template bool loadDataFromMatlab<bool>(const mxArray* mxa);
370 template int loadDataFromMatlab<int>(const mxArray* mxa);
371 template double loadDataFromMatlab<double>(const mxArray* mxa);
372 template complex_t loadDataFromMatlab<complex_t>(const mxArray* mxa);
373 template string loadDataFromMatlab<string>(const mxArray* mxa);
374 template RCP<Xpetra_ordinal_vector> loadDataFromMatlab<RCP<Xpetra_ordinal_vector> >(const mxArray* mxa);
375 template RCP<Tpetra_MultiVector_double> loadDataFromMatlab<RCP<Tpetra_MultiVector_double> >(const mxArray* mxa);
376 template RCP<Tpetra_MultiVector_complex> loadDataFromMatlab<RCP<Tpetra_MultiVector_complex> >(const mxArray* mxa);
377 template RCP<Tpetra_CrsMatrix_double> loadDataFromMatlab<RCP<Tpetra_CrsMatrix_double> >(const mxArray* mxa);
378 template RCP<Tpetra_CrsMatrix_complex> loadDataFromMatlab<RCP<Tpetra_CrsMatrix_complex> >(const mxArray* mxa);
379 template RCP<Xpetra_Matrix_double> loadDataFromMatlab<RCP<Xpetra_Matrix_double> >(const mxArray* mxa);
380 template RCP<Xpetra_Matrix_complex> loadDataFromMatlab<RCP<Xpetra_Matrix_complex> >(const mxArray* mxa);
381 template RCP<Xpetra_MultiVector_double> loadDataFromMatlab<RCP<Xpetra_MultiVector_double> >(const mxArray* mxa);
382 template RCP<Xpetra_MultiVector_complex> loadDataFromMatlab<RCP<Xpetra_MultiVector_complex> >(const mxArray* mxa);
383 template RCP<Epetra_CrsMatrix> loadDataFromMatlab<RCP<Epetra_CrsMatrix> >(const mxArray* mxa);
384 template RCP<Epetra_MultiVector> loadDataFromMatlab<RCP<Epetra_MultiVector> >(const mxArray* mxa);
385 template RCP<MAggregates> loadDataFromMatlab<RCP<MAggregates> >(const mxArray* mxa);
386 template RCP<MAmalInfo> loadDataFromMatlab<RCP<MAmalInfo> >(const mxArray* mxa);
387 
388 template mxArray* saveDataToMatlab(bool& data);
389 template mxArray* saveDataToMatlab(int& data);
390 template mxArray* saveDataToMatlab(double& data);
391 template mxArray* saveDataToMatlab(complex_t& data);
392 template mxArray* saveDataToMatlab(string& data);
393 template mxArray* saveDataToMatlab(RCP<Xpetra_ordinal_vector>& data);
394 template mxArray* saveDataToMatlab(RCP<Tpetra_MultiVector_double>& data);
395 template mxArray* saveDataToMatlab(RCP<Tpetra_MultiVector_complex>& data);
396 template mxArray* saveDataToMatlab(RCP<Tpetra_CrsMatrix_double>& data);
397 template mxArray* saveDataToMatlab(RCP<Tpetra_CrsMatrix_complex>& data);
398 template mxArray* saveDataToMatlab(RCP<Xpetra_Matrix_double>& data);
399 template mxArray* saveDataToMatlab(RCP<Xpetra_Matrix_complex>& data);
400 template mxArray* saveDataToMatlab(RCP<Xpetra_MultiVector_double>& data);
401 template mxArray* saveDataToMatlab(RCP<Xpetra_MultiVector_complex>& data);
402 template mxArray* saveDataToMatlab(RCP<Epetra_CrsMatrix>& data);
403 template mxArray* saveDataToMatlab(RCP<Epetra_MultiVector>& data);
404 template mxArray* saveDataToMatlab(RCP<MAggregates>& data);
405 template mxArray* saveDataToMatlab(RCP<MAmalInfo>& data);
406 
407 template vector<RCP<MuemexArg> > processNeeds<double>(const Factory* factory, string& needsParam, Level& lvl);
408 template vector<RCP<MuemexArg> > processNeeds<complex_t>(const Factory* factory, string& needsParam, Level& lvl);
409 template void processProvides<double>(vector<RCP<MuemexArg> >& mexOutput, const Factory* factory, string& providesParam, Level& lvl);
410 template void processProvides<complex_t>(vector<RCP<MuemexArg> >& mexOutput, const Factory* factory, string& providesParam, Level& lvl);
411 
412 } // namespace MueLu
413 #endif // HAVE_MUELU_MATLAB
bool isValidMatlabAggregates(const mxArray *mxa)
template mxArray * saveDataToMatlab(bool &data)
std::vector< std::string > tokenizeList(const std::string &params)
mxArray * createMatlabSparse< complex_t >(int numRows, int numCols, int nnz)
bool rewrap_ints
template vector< RCP< MuemexArg > > processNeeds< complex_t >(const Factory *factory, string &needsParam, Level &lvl)
template void processProvides< complex_t >(vector< RCP< MuemexArg > > &mexOutput, const Factory *factory, string &providesParam, Level &lvl)
mxArray * saveAmalInfo(RCP< MAmalInfo > &amalInfo)
std::vector< RCP< MuemexArg > > callMatlab(std::string function, int numOutputs, std::vector< RCP< MuemexArg > > args)
template vector< RCP< MuemexArg > > processNeeds< double >(const Factory *factory, string &needsParam, Level &lvl)
void fillMatlabArray< double >(double *array, const mxArray *mxa, int n)
bool isValidMatlabGraph(const mxArray *mxa)
template string loadDataFromMatlab< string >(const mxArray *mxa)
Teuchos::RCP< Teuchos::ParameterList > getInputParamList()
template void processProvides< double >(vector< RCP< MuemexArg > > &mexOutput, const Factory *factory, string &providesParam, Level &lvl)
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
void fillMatlabArray< complex_t >(complex_t *array, const mxArray *mxa, int n)
mxArray * createMatlabSparse< double >(int numRows, int numCols, int nnz)
int * mwIndex_to_int(int N, mwIndex *mwi_array)
template complex_t loadDataFromMatlab< complex_t >(const mxArray *mxa)
template int loadDataFromMatlab< int >(const mxArray *mxa)
template bool loadDataFromMatlab< bool >(const mxArray *mxa)
mxArray * createMatlabMultiVector< complex_t >(int numRows, int numCols)
void callMatlabNoArgs(std::string function)
std::complex< double > complex_t
mxArray * createMatlabMultiVector< double >(int numRows, int numCols)
template double loadDataFromMatlab< double >(const mxArray *mxa)
int mwIndex
Teuchos::RCP< MuemexArg > convertMatlabVar(const mxArray *mxa)