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 // ***********************************************************************
4 //
5 // MueLu: A package for multigrid based preconditioning
6 // Copyright 2012 Sandia Corporation
7 //
8 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
9 // the U.S. Government retains certain rights in this software.
10 //
11 // Redistribution and use in source and binary forms, with or without
12 // modification, are permitted provided that the following conditions are
13 // met:
14 //
15 // 1. Redistributions of source code must retain the above copyright
16 // notice, this list of conditions and the following disclaimer.
17 //
18 // 2. Redistributions in binary form must reproduce the above copyright
19 // notice, this list of conditions and the following disclaimer in the
20 // documentation and/or other materials provided with the distribution.
21 //
22 // 3. Neither the name of the Corporation nor the names of the
23 // contributors may be used to endorse or promote products derived from
24 // this software without specific prior written permission.
25 //
26 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
27 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
30 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
31 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
32 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
33 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
34 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
35 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
36 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37 //
38 // Questions? Contact
39 // Jonathan Hu (jhu@sandia.gov)
40 // Andrey Prokopenko (aprokop@sandia.gov)
41 // Ray Tuminaro (rstumin@sandia.gov)
42 //
43 // ***********************************************************************
44 //
45 // @HEADER
47 
48 #if !defined(HAVE_MUELU_MATLAB) || !defined(HAVE_MUELU_EPETRA) || !defined(HAVE_MUELU_TPETRA)
49 #error "Muemex types require MATLAB, Epetra and Tpetra."
50 #else
51 
52 /* Stuff for MATLAB R2006b vs. previous versions */
53 #if(defined(MX_API_VER) && MX_API_VER >= 0x07030000)
54 #else
55 typedef int mwIndex;
56 #endif
57 
58 using namespace std;
59 using namespace Teuchos;
60 
61 namespace MueLu {
62 
63 /* Explicit instantiation of MuemexData variants */
64  template class MuemexData<RCP<Xpetra::MultiVector<double, mm_LocalOrd, mm_GlobalOrd, mm_node_t> > >;
65  template class MuemexData<RCP<Xpetra::MultiVector<complex_t, mm_LocalOrd, mm_GlobalOrd, mm_node_t> > >;
66  template class MuemexData<RCP<Xpetra::Matrix<double, mm_LocalOrd, mm_GlobalOrd, mm_node_t> > >;
67  template class MuemexData<RCP<Xpetra::Matrix<complex_t, mm_LocalOrd, mm_GlobalOrd, mm_node_t> > >;
68  template class MuemexData<RCP<MAggregates>>;
69  template class MuemexData<RCP<MAmalInfo>>;
70  template class MuemexData<int>;
71  template class MuemexData<bool>;
72  template class MuemexData<complex_t>;
73  template class MuemexData<string>;
74  template class MuemexData<double>;
75  template class MuemexData<RCP<Tpetra::CrsMatrix<double, mm_LocalOrd, mm_GlobalOrd, mm_node_t> > >;
76  template class MuemexData<RCP<Tpetra::CrsMatrix<complex_t, mm_LocalOrd, mm_GlobalOrd, mm_node_t> > >;
77  template class MuemexData<RCP<Epetra_MultiVector> >;
78  template class MuemexData<RCP<Tpetra::MultiVector<double, mm_LocalOrd, mm_GlobalOrd, mm_node_t> > >;
79  template class MuemexData<RCP<Tpetra::MultiVector<complex_t, mm_LocalOrd, mm_GlobalOrd, mm_node_t> > >;
80  template class MuemexData<RCP<Xpetra::Vector<mm_LocalOrd, mm_LocalOrd, mm_GlobalOrd, mm_node_t>>>;
81 
82 //Flag set to true if MATLAB's CSC matrix index type is not int (usually false)
83 bool rewrap_ints = sizeof(int) != sizeof(mwIndex);
84 
85 int* mwIndex_to_int(int N, mwIndex* mwi_array)
86 {
87  //int* rv = (int*) malloc(N * sizeof(int));
88  int* rv = new int[N]; // not really better but may avoid confusion for valgrind
89  for(int i = 0; i < N; i++)
90  rv[i] = (int) mwi_array[i];
91  return rv;
92 }
93 
94 /* ******************************* */
95 /* Specializations */
96 /* ******************************* */
97 
98 template<> mxArray* createMatlabSparse<double>(int numRows, int numCols, int nnz)
99 {
100  return mxCreateSparse(numRows, numCols, nnz, mxREAL);
101 }
102 
103 template<> mxArray* createMatlabSparse<complex_t>(int numRows, int numCols, int nnz)
104 {
105  return mxCreateSparse(numRows, numCols, nnz, mxCOMPLEX);
106 }
107 
108 template<> void fillMatlabArray<double>(double* array, const mxArray* mxa, int n)
109 {
110  memcpy(mxGetPr(mxa), array, n * sizeof(double));
111 }
112 
113 template<> void fillMatlabArray<complex_t>(complex_t* array, const mxArray* mxa, int n)
114 {
115  double* pr = mxGetPr(mxa);
116  double* pi = mxGetPi(mxa);
117  for(int i = 0; i < n; i++)
118  {
119  pr[i] = std::real<double>(array[i]);
120  pi[i] = std::imag<double>(array[i]);
121  }
122 }
123 
124 /******************************/
125 /* Callback Functions */
126 /******************************/
127 
128 void callMatlabNoArgs(std::string function)
129 {
130  int result = mexEvalString(function.c_str());
131  if(result != 0)
132  mexPrintf("An error occurred while running a MATLAB command.");\
133 }
134 
135 std::vector<RCP<MuemexArg>> callMatlab(std::string function, int numOutputs, std::vector<RCP<MuemexArg>> args)
136 {
137  using Teuchos::rcp_static_cast;
138  mxArray** matlabArgs = new mxArray* [args.size()];
139  mxArray** matlabOutput = new mxArray* [numOutputs];
140  std::vector<RCP<MuemexArg>> output;
141 
142  for(int i = 0; i < int(args.size()); i++)
143  {
144  try
145  {
146  switch(args[i]->type)
147  {
148  case BOOL:
149  matlabArgs[i] = rcp_static_cast<MuemexData<bool>, MuemexArg>(args[i])->convertToMatlab();
150  break;
151  case INT:
152  matlabArgs[i] = rcp_static_cast<MuemexData<int>, MuemexArg>(args[i])->convertToMatlab();
153  break;
154  case DOUBLE:
155  matlabArgs[i] = rcp_static_cast<MuemexData<double>, MuemexArg>(args[i])->convertToMatlab();
156  break;
157  case STRING:
158  matlabArgs[i] = rcp_static_cast<MuemexData<std::string>, MuemexArg>(args[i])->convertToMatlab();
159  break;
160  case COMPLEX:
161  matlabArgs[i] = rcp_static_cast<MuemexData<complex_t>, MuemexArg>(args[i])->convertToMatlab();
162  break;
163  case XPETRA_MAP:
164  matlabArgs[i] = rcp_static_cast<MuemexData<RCP<Xpetra_map>>, MuemexArg>(args[i])->convertToMatlab();
165  break;
167  matlabArgs[i] = rcp_static_cast<MuemexData<RCP<Xpetra_ordinal_vector>>, MuemexArg>(args[i])->convertToMatlab();
168  break;
170  matlabArgs[i] = rcp_static_cast<MuemexData<RCP<Tpetra::MultiVector<double, mm_LocalOrd, mm_GlobalOrd, mm_node_t>>>, MuemexArg>(args[i])->convertToMatlab();
171  break;
173  matlabArgs[i] = rcp_static_cast<MuemexData<RCP<Tpetra::MultiVector<complex_t, mm_LocalOrd, mm_GlobalOrd, mm_node_t>>>, MuemexArg>(args[i])->convertToMatlab();
174  break;
176  matlabArgs[i] = rcp_static_cast<MuemexData<RCP<Tpetra::CrsMatrix<double, mm_LocalOrd, mm_GlobalOrd, mm_node_t>>>, MuemexArg>(args[i])->convertToMatlab();
177  break;
179  matlabArgs[i] = rcp_static_cast<MuemexData<RCP<Tpetra::CrsMatrix<complex_t, mm_LocalOrd, mm_GlobalOrd, mm_node_t>>>, MuemexArg>(args[i])->convertToMatlab();
180  break;
182  matlabArgs[i] = rcp_static_cast<MuemexData<RCP<Xpetra_Matrix_double>>, MuemexArg>(args[i])->convertToMatlab();
183  break;
185  matlabArgs[i] = rcp_static_cast<MuemexData<RCP<Xpetra_Matrix_complex>>, MuemexArg>(args[i])->convertToMatlab();
186  break;
188  matlabArgs[i] = rcp_static_cast<MuemexData<RCP<Xpetra_MultiVector_double>>, MuemexArg>(args[i])->convertToMatlab();
189  break;
191  matlabArgs[i] = rcp_static_cast<MuemexData<RCP<Xpetra_MultiVector_complex>>, MuemexArg>(args[i])->convertToMatlab();
192  break;
193  case EPETRA_CRSMATRIX:
194  matlabArgs[i] = rcp_static_cast<MuemexData<RCP<Epetra_CrsMatrix>>, MuemexArg>(args[i])->convertToMatlab();
195  break;
196  case EPETRA_MULTIVECTOR:
197  matlabArgs[i] = rcp_static_cast<MuemexData<RCP<Epetra_MultiVector>>, MuemexArg>(args[i])->convertToMatlab();
198  break;
199  case AGGREGATES:
200  matlabArgs[i] = rcp_static_cast<MuemexData<RCP<MAggregates>>, MuemexArg>(args[i])->convertToMatlab();
201  break;
202  case AMALGAMATION_INFO:
203  matlabArgs[i] = rcp_static_cast<MuemexData<RCP<MAmalInfo>>, MuemexArg>(args[i])->convertToMatlab();
204  break;
205  case GRAPH:
206  matlabArgs[i] = rcp_static_cast<MuemexData<RCP<MGraph>>, MuemexArg>(args[i])->convertToMatlab();
207 #ifdef HAVE_MUELU_INTREPID2
208  case FIELDCONTAINER_ORDINAL:
209  matlabArgs[i] = rcp_static_cast<MuemexData<RCP<FieldContainer_ordinal>>, MuemexArg>(args[i])->convertToMatlab();
210  break;
211 #endif
212  }
213  }
214  catch (std::exception& e)
215  {
216  mexPrintf("An error occurred while converting arg #%d to MATLAB:\n", i);
217  std::cout << e.what() << std::endl;
218  mexPrintf("Passing 0 instead.\n");
219  matlabArgs[i] = mxCreateDoubleScalar(0);
220  }
221  }
222  //now matlabArgs is populated with MATLAB data types
223  int result = mexCallMATLAB(numOutputs, matlabOutput, args.size(), matlabArgs, function.c_str());
224  if(result != 0)
225  mexPrintf("Matlab encountered an error while running command through muemexCallbacks.\n");
226  //now, if all went well, matlabOutput contains all the output to return to user
227  for(int i = 0; i < numOutputs; i++)
228  {
229  try
230  {
231  output.push_back(convertMatlabVar(matlabOutput[i]));
232  }
233  catch(std::exception& e)
234  {
235  mexPrintf("An error occurred while converting output #%d from MATLAB:\n", i);
236  std::cout << e.what() << std::endl;
237  }
238  }
239  delete[] matlabOutput;
240  delete[] matlabArgs;
241  return output;
242 }
243 
244 /******************************/
245 /* More utility functions */
246 /******************************/
247 
248 template<> mxArray* createMatlabMultiVector<double>(int numRows, int numCols)
249 {
250  return mxCreateDoubleMatrix(numRows, numCols, mxREAL);
251 }
252 
253 template<> mxArray* createMatlabMultiVector<complex_t>(int numRows, int numCols)
254 {
255  return mxCreateDoubleMatrix(numRows, numCols, mxCOMPLEX);
256 }
257 
258 mxArray* saveAmalInfo(RCP<MAmalInfo>& amalInfo)
259 {
260  throw runtime_error("AmalgamationInfo not supported in MueMex yet.");
261  return mxCreateDoubleScalar(0);
262 }
263 
264 bool isValidMatlabAggregates(const mxArray* mxa)
265 {
266  bool isValidAggregates = true;
267  if(!mxIsStruct(mxa))
268  return false;
269  int numFields = mxGetNumberOfFields(mxa); //check that struct has correct # of fields
270  if(numFields != 5)
271  isValidAggregates = false;
272  if(isValidAggregates)
273  {
274  const char* mem1 = mxGetFieldNameByNumber(mxa, 0);
275  if(mem1 == NULL || strcmp(mem1, "nVertices") != 0)
276  isValidAggregates = false;
277  const char* mem2 = mxGetFieldNameByNumber(mxa, 1);
278  if(mem2 == NULL || strcmp(mem2, "nAggregates") != 0)
279  isValidAggregates = false;
280  const char* mem3 = mxGetFieldNameByNumber(mxa, 2);
281  if(mem3 == NULL || strcmp(mem3, "vertexToAggID") != 0)
282  isValidAggregates = false;
283  const char* mem4 = mxGetFieldNameByNumber(mxa, 3);
284  if(mem3 == NULL || strcmp(mem4, "rootNodes") != 0)
285  isValidAggregates = false;
286  const char* mem5 = mxGetFieldNameByNumber(mxa, 4);
287  if(mem4 == NULL || strcmp(mem5, "aggSizes") != 0)
288  isValidAggregates = false;
289  }
290  return isValidAggregates;
291 }
292 
293 bool isValidMatlabGraph(const mxArray* mxa)
294 {
295  bool isValidGraph = true;
296  if(!mxIsStruct(mxa))
297  return false;
298  int numFields = mxGetNumberOfFields(mxa); //check that struct has correct # of fields
299  if(numFields != 2)
300  isValidGraph = false;
301  if(isValidGraph)
302  {
303  const char* mem1 = mxGetFieldNameByNumber(mxa, 0);
304  if(mem1 == NULL || strcmp(mem1, "edges") != 0)
305  isValidGraph = false;
306  const char* mem2 = mxGetFieldNameByNumber(mxa, 1);
307  if(mem2 == NULL || strcmp(mem2, "boundaryNodes") != 0)
308  isValidGraph = false;
309  }
310  return isValidGraph;
311 }
312 
313 std::vector<std::string> tokenizeList(const std::string& params)
314 {
315  using namespace std;
316  vector<string> rlist;
317  const char* delims = ",";
318  char* copy = (char*) malloc(params.length() + 1);
319  strcpy(copy, params.c_str());
320  char* mark = (char*) strtok(copy, delims);
321  while(mark != NULL)
322  {
323  //Remove leading and trailing whitespace in token
324  char* tail = mark + strlen(mark) - 1;
325  while(*mark == ' ')
326  mark++;
327  while(*tail == ' ' && tail > mark)
328  tail--;
329  tail++;
330  *tail = 0;
331  string tok(mark); //copies the characters to string object
332  rlist.push_back(tok);
333  mark = strtok(NULL, delims);
334  }
335  free(copy);
336  return rlist;
337 }
338 
340 {
341  using namespace Teuchos;
342  RCP<ParameterList> validParamList = rcp(new ParameterList());
343  validParamList->set<RCP<const FactoryBase>>("A", Teuchos::null, "Factory for the matrix A.");
344  validParamList->set<RCP<const FactoryBase>>("P", Teuchos::null, "Factory for the prolongator.");
345  validParamList->set<RCP<const FactoryBase>>("R", Teuchos::null, "Factory for the restrictor.");
346  validParamList->set<RCP<const FactoryBase>>("Ptent", Teuchos::null, "Factory for the tentative (unsmoothed) prolongator.");
347  validParamList->set<RCP<const FactoryBase>>("Coordinates", Teuchos::null, "Factory for the node coordinates.");
348  validParamList->set<RCP<const FactoryBase>>("Nullspace", Teuchos::null, "Factory for the nullspace.");
349  validParamList->set<RCP<const FactoryBase>>("Aggregates", Teuchos::null, "Factory for the aggregates.");
350  validParamList->set<RCP<const FactoryBase>>("UnamalgamationInfo", Teuchos::null, "Factory for amalgamation.");
351 #ifdef HAVE_MUELU_INTREPID2
352  validParamList->set<RCP<const FactoryBase>>("pcoarsen: element to node map", Teuchos::null, "Generating factory of the element to node map");
353 #endif
354  return validParamList;
355 }
356 
358 {
359  switch(mxGetClassID(mxa))
360  {
361  case mxCHAR_CLASS:
362  //string
363  return rcp_implicit_cast<MuemexArg>(rcp(new MuemexData<std::string>(mxa)));
364  break;
365  case mxLOGICAL_CLASS:
366  //boolean
367  return rcp_implicit_cast<MuemexArg>(rcp(new MuemexData<bool>(mxa)));
368  break;
369  case mxINT32_CLASS:
370  if(mxGetM(mxa) == 1 && mxGetN(mxa) == 1)
371  //individual integer
372  return rcp_implicit_cast<MuemexArg>(rcp(new MuemexData<int>(mxa)));
373  else if(mxGetM(mxa) != 1 || mxGetN(mxa) != 1)
374  //ordinal vector
375  return rcp_implicit_cast<MuemexArg>(rcp(new MuemexData<RCP<Xpetra_ordinal_vector>>(mxa)));
376  else
377  throw std::runtime_error("Error: Don't know what to do with integer array.\n");
378  break;
379  case mxDOUBLE_CLASS:
380  if(mxGetM(mxa) == 1 && mxGetN(mxa) == 1)
381  {
382  if(mxIsComplex(mxa))
383  //single double (scalar, real)
384  return rcp_implicit_cast<MuemexArg>(rcp(new MuemexData<complex_t>(mxa)));
385  else
386  //single complex scalar
387  return rcp_implicit_cast<MuemexArg>(rcp(new MuemexData<double>(mxa)));
388  }
389  else if(mxIsSparse(mxa)) //use a CRS matrix
390  {
391  //Default to Tpetra matrix for this
392  if(mxIsComplex(mxa))
393  //complex matrix
394  return rcp_implicit_cast<MuemexArg>(rcp(new MuemexData<RCP<Xpetra_Matrix_complex>>(mxa)));
395  else
396  //real-valued matrix
397  return rcp_implicit_cast<MuemexArg>(rcp(new MuemexData<RCP<Xpetra_Matrix_double>>(mxa)));
398  }
399  else
400  {
401  //Default to Xpetra multivector for this case
402  if(mxIsComplex(mxa))
403  return rcp_implicit_cast<MuemexArg>(rcp(new MuemexData<RCP<Xpetra::MultiVector<complex_t, mm_LocalOrd, mm_GlobalOrd, mm_node_t>>>(mxa)));
404  else
405  return rcp_implicit_cast<MuemexArg>(rcp(new MuemexData<RCP<Xpetra::MultiVector<double, mm_LocalOrd, mm_GlobalOrd, mm_node_t>>>(mxa)));
406  }
407  break;
408  case mxSTRUCT_CLASS:
409  {
410  //the only thing that should get here currently is an Aggregates struct or Graph struct
411  //verify that it has the correct fields with the correct types
412  //also assume that aggregates data will not be stored in an array of more than 1 element.
413  if(isValidMatlabAggregates(mxa)) {
414  return rcp_implicit_cast<MuemexArg>(rcp(new MuemexData<RCP<MAggregates>>(mxa)));
415  } else if(isValidMatlabGraph(mxa)) {
416  return rcp_implicit_cast<MuemexArg>(rcp(new MuemexData<RCP<MGraph>>(mxa)));
417  } else {
418  throw runtime_error("Invalid aggregates or graph struct passed in from MATLAB.");
419  return Teuchos::null;
420  }
421  break;
422  }
423  default:
424  throw std::runtime_error("MATLAB returned an unsupported type as a function output.\n");
425  return Teuchos::null;
426  }
427 }
428 
429 /******************************/
430 /* Explicit Instantiations */
431 /******************************/
432 
433 template bool loadDataFromMatlab<bool>(const mxArray* mxa);
434 template int loadDataFromMatlab<int>(const mxArray* mxa);
435 template double loadDataFromMatlab<double>(const mxArray* mxa);
436 template complex_t loadDataFromMatlab<complex_t>(const mxArray* mxa);
437 template string loadDataFromMatlab<string>(const mxArray* mxa);
438 template RCP<Xpetra_ordinal_vector> loadDataFromMatlab<RCP<Xpetra_ordinal_vector>>(const mxArray* mxa);
439 template RCP<Tpetra_MultiVector_double> loadDataFromMatlab<RCP<Tpetra_MultiVector_double>>(const mxArray* mxa);
440 template RCP<Tpetra_MultiVector_complex> loadDataFromMatlab<RCP<Tpetra_MultiVector_complex>>(const mxArray* mxa);
441 template RCP<Tpetra_CrsMatrix_double> loadDataFromMatlab<RCP<Tpetra_CrsMatrix_double>>(const mxArray* mxa);
442 template RCP<Tpetra_CrsMatrix_complex> loadDataFromMatlab<RCP<Tpetra_CrsMatrix_complex>>(const mxArray* mxa);
443 template RCP<Xpetra_Matrix_double> loadDataFromMatlab<RCP<Xpetra_Matrix_double>>(const mxArray* mxa);
444 template RCP<Xpetra_Matrix_complex> loadDataFromMatlab<RCP<Xpetra_Matrix_complex>>(const mxArray* mxa);
445 template RCP<Xpetra_MultiVector_double> loadDataFromMatlab<RCP<Xpetra_MultiVector_double>>(const mxArray* mxa);
446 template RCP<Xpetra_MultiVector_complex> loadDataFromMatlab<RCP<Xpetra_MultiVector_complex>>(const mxArray* mxa);
447 template RCP<Epetra_CrsMatrix> loadDataFromMatlab<RCP<Epetra_CrsMatrix>>(const mxArray* mxa);
448 template RCP<Epetra_MultiVector> loadDataFromMatlab<RCP<Epetra_MultiVector>>(const mxArray* mxa);
449 template RCP<MAggregates> loadDataFromMatlab<RCP<MAggregates>>(const mxArray* mxa);
450 template RCP<MAmalInfo> loadDataFromMatlab<RCP<MAmalInfo>>(const mxArray* mxa);
451 
452 template mxArray* saveDataToMatlab(bool& data);
453 template mxArray* saveDataToMatlab(int& data);
454 template mxArray* saveDataToMatlab(double& data);
455 template mxArray* saveDataToMatlab(complex_t& data);
456 template mxArray* saveDataToMatlab(string& data);
457 template mxArray* saveDataToMatlab(RCP<Xpetra_ordinal_vector>& data);
458 template mxArray* saveDataToMatlab(RCP<Tpetra_MultiVector_double>& data);
459 template mxArray* saveDataToMatlab(RCP<Tpetra_MultiVector_complex>& data);
460 template mxArray* saveDataToMatlab(RCP<Tpetra_CrsMatrix_double>& data);
461 template mxArray* saveDataToMatlab(RCP<Tpetra_CrsMatrix_complex>& data);
462 template mxArray* saveDataToMatlab(RCP<Xpetra_Matrix_double>& data);
463 template mxArray* saveDataToMatlab(RCP<Xpetra_Matrix_complex>& data);
464 template mxArray* saveDataToMatlab(RCP<Xpetra_MultiVector_double>& data);
465 template mxArray* saveDataToMatlab(RCP<Xpetra_MultiVector_complex>& data);
466 template mxArray* saveDataToMatlab(RCP<Epetra_CrsMatrix>& data);
467 template mxArray* saveDataToMatlab(RCP<Epetra_MultiVector>& data);
468 template mxArray* saveDataToMatlab(RCP<MAggregates>& data);
469 template mxArray* saveDataToMatlab(RCP<MAmalInfo>& data);
470 
471 template vector<RCP<MuemexArg>> processNeeds<double>(const Factory* factory, string& needsParam, Level& lvl);
472 template vector<RCP<MuemexArg>> processNeeds<complex_t>(const Factory* factory, string& needsParam, Level& lvl);
473 template void processProvides<double>(vector<RCP<MuemexArg>>& mexOutput, const Factory* factory, string& providesParam, Level& lvl);
474 template void processProvides<complex_t>(vector<RCP<MuemexArg>>& mexOutput, const Factory* factory, string& providesParam, Level& lvl);
475 
476 }//end namespace
477 #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)
mxArray * saveAmalInfo(RCP< MAmalInfo > &amalInfo)
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()
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)
template void processProvides< complex_t >(vector< RCP< MuemexArg >> &mexOutput, const Factory *factory, string &providesParam, Level &lvl)
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
template void processProvides< double >(vector< RCP< MuemexArg >> &mexOutput, const Factory *factory, string &providesParam, Level &lvl)
std::vector< RCP< MuemexArg > > callMatlab(std::string function, int numOutputs, std::vector< RCP< MuemexArg >> args)
Teuchos::RCP< MuemexArg > convertMatlabVar(const mxArray *mxa)