xref: /petsc/src/mat/impls/aij/seq/matlab/aijmatlab.c (revision 22612f2f7cceb60caedd65384cdf99fc989f2aeb)
1 #define PETSCMAT_DLL
2 
3 /*
4         Provides an interface for the Matlab engine sparse solver
5 
6 */
7 #include "src/mat/impls/aij/seq/aij.h"
8 
9 #include "engine.h"   /* Matlab include file */
10 #include "mex.h"      /* Matlab include file */
11 
12 typedef struct {
13   PetscErrorCode (*MatDuplicate)(Mat,MatDuplicateOption,Mat*);
14   PetscErrorCode (*MatView)(Mat,PetscViewer);
15   PetscErrorCode (*MatLUFactorSymbolic)(Mat,IS,IS,MatFactorInfo*,Mat*);
16   PetscErrorCode (*MatILUDTFactor)(Mat,IS,IS,MatFactorInfo*,Mat*);
17   PetscErrorCode (*MatDestroy)(Mat);
18 } Mat_Matlab;
19 
20 
21 EXTERN_C_BEGIN
22 #undef __FUNCT__
23 #define __FUNCT__ "MatMatlabEnginePut_Matlab"
24 PetscErrorCode PETSCMAT_DLLEXPORT MatMatlabEnginePut_Matlab(PetscObject obj,void *mengine)
25 {
26   PetscErrorCode ierr;
27   Mat            B = (Mat)obj;
28   mxArray        *mat;
29   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*)B->data;
30 
31   PetscFunctionBegin;
32   mat  = mxCreateSparse(B->cmap.n,B->rmap.n,aij->nz,mxREAL);
33   ierr = PetscMemcpy(mxGetPr(mat),aij->a,aij->nz*sizeof(PetscScalar));CHKERRQ(ierr);
34   /* Matlab stores by column, not row so we pass in the transpose of the matrix */
35   ierr = PetscMemcpy(mxGetIr(mat),aij->j,aij->nz*sizeof(int));CHKERRQ(ierr);
36   ierr = PetscMemcpy(mxGetJc(mat),aij->i,(B->rmap.n+1)*sizeof(int));CHKERRQ(ierr);
37 
38   /* Matlab indices start at 0 for sparse (what a surprise) */
39 
40   ierr = PetscObjectName(obj);CHKERRQ(ierr);
41   engPutVariable((Engine *)mengine,obj->name,mat);
42   PetscFunctionReturn(0);
43 }
44 EXTERN_C_END
45 
46 EXTERN_C_BEGIN
47 #undef __FUNCT__
48 #define __FUNCT__ "MatMatlabEngineGet_Matlab"
49 PetscErrorCode PETSCMAT_DLLEXPORT MatMatlabEngineGet_Matlab(PetscObject obj,void *mengine)
50 {
51   PetscErrorCode ierr;
52   int            ii;
53   Mat            mat = (Mat)obj;
54   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*)mat->data;
55   mxArray        *mmat;
56 
57   PetscFunctionBegin;
58   ierr = MatSeqXAIJFreeAIJ(mat,&aij->a,&aij->j,&aij->i);CHKERRQ(ierr);
59 
60   mmat = engGetVariable((Engine *)mengine,obj->name);
61 
62   aij->nz           = (mxGetJc(mmat))[mat->rmap.n];
63   ierr  = PetscMalloc3(aij->nz,PetscScalar,&aij->a,aij->nz,PetscInt,&aij->j,mat->rmap.n+1,PetscInt,&aij->i);CHKERRQ(ierr);
64   aij->singlemalloc = PETSC_TRUE;
65 
66   ierr = PetscMemcpy(aij->a,mxGetPr(mmat),aij->nz*sizeof(PetscScalar));CHKERRQ(ierr);
67   /* Matlab stores by column, not row so we pass in the transpose of the matrix */
68   ierr = PetscMemcpy(aij->j,mxGetIr(mmat),aij->nz*sizeof(int));CHKERRQ(ierr);
69   ierr = PetscMemcpy(aij->i,mxGetJc(mmat),(mat->rmap.n+1)*sizeof(int));CHKERRQ(ierr);
70 
71   for (ii=0; ii<mat->rmap.n; ii++) {
72     aij->ilen[ii] = aij->imax[ii] = aij->i[ii+1] - aij->i[ii];
73   }
74 
75   ierr = MatAssemblyBegin(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
76   ierr = MatAssemblyEnd(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
77 
78   PetscFunctionReturn(0);
79 }
80 EXTERN_C_END
81 
82 EXTERN_C_BEGIN
83 #undef __FUNCT__
84 #define __FUNCT__ "MatConvert_Matlab_SeqAIJ"
85 PetscErrorCode PETSCMAT_DLLEXPORT MatConvert_Matlab_SeqAIJ(Mat A,MatType type,MatReuse reuse,Mat *newmat)
86 {
87   PetscErrorCode ierr;
88   Mat            B=*newmat;
89   Mat_Matlab    *lu=(Mat_Matlab*)A->spptr;
90 
91   PetscFunctionBegin;
92   if (reuse == MAT_INITIAL_MATRIX) {
93     ierr = MatDuplicate(A,MAT_COPY_VALUES,&B);CHKERRQ(ierr);
94   }
95   B->ops->duplicate        = lu->MatDuplicate;
96   B->ops->view             = lu->MatView;
97   B->ops->lufactorsymbolic = lu->MatLUFactorSymbolic;
98   B->ops->iludtfactor      = lu->MatILUDTFactor;
99   B->ops->destroy          = lu->MatDestroy;
100 
101   ierr = PetscFree(lu);CHKERRQ(ierr);
102 
103   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_matlab_C","",PETSC_NULL);CHKERRQ(ierr);
104   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_matlab_seqaij_C","",PETSC_NULL);CHKERRQ(ierr);
105   ierr = PetscObjectComposeFunction((PetscObject)B,"PetscMatlabEnginePut_C","",PETSC_NULL);CHKERRQ(ierr);
106   ierr = PetscObjectComposeFunction((PetscObject)B,"PetscMatlabEngineGet_C","",PETSC_NULL);CHKERRQ(ierr);
107 
108   ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr);
109   *newmat = B;
110   PetscFunctionReturn(0);
111 }
112 EXTERN_C_END
113 
114 #undef __FUNCT__
115 #define __FUNCT__ "MatDestroy_Matlab"
116 PetscErrorCode MatDestroy_Matlab(Mat A)
117 {
118   PetscErrorCode ierr;
119 
120   PetscFunctionBegin;
121   ierr = MatConvert_Matlab_SeqAIJ(A,MATSEQAIJ,MAT_REUSE_MATRIX,&A);CHKERRQ(ierr);
122   ierr = (*A->ops->destroy)(A);CHKERRQ(ierr);
123   PetscFunctionReturn(0);
124 }
125 
126 #undef __FUNCT__
127 #define __FUNCT__ "MatSolve_Matlab"
128 PetscErrorCode MatSolve_Matlab(Mat A,Vec b,Vec x)
129 {
130   PetscErrorCode ierr;
131   const char     *_A,*_b,*_x;
132 
133   PetscFunctionBegin;
134   /* make sure objects have names; use default if not */
135   ierr = PetscObjectName((PetscObject)b);CHKERRQ(ierr);
136   ierr = PetscObjectName((PetscObject)x);CHKERRQ(ierr);
137 
138   ierr = PetscObjectGetName((PetscObject)A,&_A);CHKERRQ(ierr);
139   ierr = PetscObjectGetName((PetscObject)b,&_b);CHKERRQ(ierr);
140   ierr = PetscObjectGetName((PetscObject)x,&_x);CHKERRQ(ierr);
141   ierr = PetscMatlabEnginePut(PETSC_MATLAB_ENGINE_(A->comm),(PetscObject)b);CHKERRQ(ierr);
142   ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(A->comm),"%s = u%s\\(l%s\\(p%s*%s));",_x,_A,_A,_A,_b);CHKERRQ(ierr);
143   ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(A->comm),"%s = 0;",_b);CHKERRQ(ierr);
144   /* ierr = PetscMatlabEnginePrintOutput(PETSC_MATLAB_ENGINE_(A->comm),stdout);CHKERRQ(ierr);  */
145   ierr = PetscMatlabEngineGet(PETSC_MATLAB_ENGINE_(A->comm),(PetscObject)x);CHKERRQ(ierr);
146   PetscFunctionReturn(0);
147 }
148 
149 #undef __FUNCT__
150 #define __FUNCT__ "MatLUFactorNumeric_Matlab"
151 PetscErrorCode MatLUFactorNumeric_Matlab(Mat A,MatFactorInfo *info,Mat *F)
152 {
153   PetscErrorCode ierr;
154   size_t         len;
155   char           *_A,*name;
156 
157   PetscFunctionBegin;
158   ierr = PetscMatlabEnginePut(PETSC_MATLAB_ENGINE_(A->comm),(PetscObject)A);CHKERRQ(ierr);
159   _A   = A->name;
160   ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(A->comm),"[l_%s,u_%s,p_%s] = lu(%s',%g);",_A,_A,_A,_A,info->dtcol);CHKERRQ(ierr);
161   ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(A->comm),"%s = 0;",_A);CHKERRQ(ierr);
162   ierr = PetscStrlen(_A,&len);CHKERRQ(ierr);
163   ierr = PetscMalloc((len+2)*sizeof(char),&name);CHKERRQ(ierr);
164   sprintf(name,"_%s",_A);
165   ierr = PetscObjectSetName((PetscObject)*F,name);CHKERRQ(ierr);
166   ierr = PetscFree(name);CHKERRQ(ierr);
167   PetscFunctionReturn(0);
168 }
169 
170 #undef __FUNCT__
171 #define __FUNCT__ "MatLUFactorSymbolic_Matlab"
172 PetscErrorCode MatLUFactorSymbolic_Matlab(Mat A,IS r,IS c,MatFactorInfo *info,Mat *F)
173 {
174   PetscErrorCode ierr;
175 
176   PetscFunctionBegin;
177   if (A->cmap.N != A->rmap.N) SETERRQ(PETSC_ERR_ARG_SIZ,"matrix must be square");
178   ierr                       = MatCreate(A->comm,F);CHKERRQ(ierr);
179   ierr                       = MatSetSizes(*F,A->rmap.n,A->cmap.n,A->rmap.n,A->cmap.n);CHKERRQ(ierr);
180   ierr                       = MatSetType(*F,A->type_name);CHKERRQ(ierr);
181   ierr                       = MatSeqAIJSetPreallocation(*F,0,PETSC_NULL);CHKERRQ(ierr);
182   (*F)->ops->solve           = MatSolve_Matlab;
183   (*F)->ops->lufactornumeric = MatLUFactorNumeric_Matlab;
184   (*F)->factor               = FACTOR_LU;
185   PetscFunctionReturn(0);
186 }
187 
188 /* ---------------------------------------------------------------------------------*/
189 #undef __FUNCT__
190 #define __FUNCT__ "MatSolve_Matlab_QR"
191 PetscErrorCode MatSolve_Matlab_QR(Mat A,Vec b,Vec x)
192 {
193   PetscErrorCode ierr;
194   const char     *_A,*_b,*_x;
195 
196   PetscFunctionBegin;
197   /* make sure objects have names; use default if not */
198   ierr = PetscObjectName((PetscObject)b);CHKERRQ(ierr);
199   ierr = PetscObjectName((PetscObject)x);CHKERRQ(ierr);
200 
201   ierr = PetscObjectGetName((PetscObject)A,&_A);CHKERRQ(ierr);
202   ierr = PetscObjectGetName((PetscObject)b,&_b);CHKERRQ(ierr);
203   ierr = PetscObjectGetName((PetscObject)x,&_x);CHKERRQ(ierr);
204   ierr = PetscMatlabEnginePut(PETSC_MATLAB_ENGINE_(A->comm),(PetscObject)b);CHKERRQ(ierr);
205   ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(A->comm),"%s = r%s\\(r%s'\\(%s*%s));",_x,_A,_A,_A+1,_b);CHKERRQ(ierr);
206   ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(A->comm),"%s = 0;",_b);CHKERRQ(ierr);
207   /* ierr = PetscMatlabEnginePrintOutput(PETSC_MATLAB_ENGINE_(A->comm),stdout);CHKERRQ(ierr);  */
208   ierr = PetscMatlabEngineGet(PETSC_MATLAB_ENGINE_(A->comm),(PetscObject)x);CHKERRQ(ierr);
209   PetscFunctionReturn(0);
210 }
211 
212 #undef __FUNCT__
213 #define __FUNCT__ "MatLUFactorNumeric_Matlab_QR"
214 PetscErrorCode MatLUFactorNumeric_Matlab_QR(Mat A,MatFactorInfo *info,Mat *F)
215 {
216   PetscErrorCode ierr;
217   size_t         len;
218   char           *_A,*name;
219 
220   PetscFunctionBegin;
221   ierr = PetscMatlabEnginePut(PETSC_MATLAB_ENGINE_(A->comm),(PetscObject)A);CHKERRQ(ierr);
222   _A   = A->name;
223   ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(A->comm),"r_%s = qr(%s');",_A,_A);CHKERRQ(ierr);
224   ierr = PetscStrlen(_A,&len);CHKERRQ(ierr);
225   ierr = PetscMalloc((len+2)*sizeof(char),&name);CHKERRQ(ierr);
226   sprintf(name,"_%s",_A);
227   ierr = PetscObjectSetName((PetscObject)*F,name);CHKERRQ(ierr);
228   ierr = PetscFree(name);CHKERRQ(ierr);
229   PetscFunctionReturn(0);
230 }
231 
232 #undef __FUNCT__
233 #define __FUNCT__ "MatLUFactorSymbolic_Matlab_QR"
234 PetscErrorCode MatLUFactorSymbolic_Matlab_QR(Mat A,IS r,IS c,MatFactorInfo *info,Mat *F)
235 {
236   PetscErrorCode ierr;
237 
238   PetscFunctionBegin;
239   if (A->cmap.N != A->rmap.N) SETERRQ(PETSC_ERR_ARG_SIZ,"matrix must be square");
240   ierr                       = MatCreate(A->comm,F);CHKERRQ(ierr);
241   ierr                       = MatSetSizes(*F,A->rmap.n,A->cmap.n,A->rmap.n,A->cmap.n);CHKERRQ(ierr);
242   ierr                       = MatSetType(*F,A->type_name);CHKERRQ(ierr);
243   ierr                       = MatSeqAIJSetPreallocation(*F,0,PETSC_NULL);CHKERRQ(ierr);
244   (*F)->ops->solve           = MatSolve_Matlab_QR;
245   (*F)->ops->lufactornumeric = MatLUFactorNumeric_Matlab_QR;
246   (*F)->factor               = FACTOR_LU;
247   (*F)->assembled            = PETSC_TRUE;  /* required by -ksp_view */
248 
249   PetscFunctionReturn(0);
250 }
251 
252 /* --------------------------------------------------------------------------------*/
253 #undef __FUNCT__
254 #define __FUNCT__ "MatILUDTFactor_Matlab"
255 PetscErrorCode MatILUDTFactor_Matlab(Mat A,IS isrow,IS iscol,MatFactorInfo *info,Mat *F)
256 {
257   PetscErrorCode ierr;
258   size_t         len;
259   char           *_A,*name;
260 
261   PetscFunctionBegin;
262   if (info->dt == PETSC_DEFAULT)      info->dt      = .005;
263   if (info->dtcol == PETSC_DEFAULT)   info->dtcol   = .01;
264   if (A->cmap.N != A->rmap.N) SETERRQ(PETSC_ERR_ARG_SIZ,"matrix must be square");
265   ierr                       = MatCreate(A->comm,F);CHKERRQ(ierr);
266   ierr                       = MatSetSizes(*F,A->rmap.n,A->cmap.n,A->rmap.n,A->cmap.n);CHKERRQ(ierr);
267   ierr                       = MatSetType(*F,A->type_name);CHKERRQ(ierr);
268   ierr                       = MatSeqAIJSetPreallocation(*F,0,PETSC_NULL);CHKERRQ(ierr);
269   (*F)->ops->solve           = MatSolve_Matlab;
270   (*F)->factor               = FACTOR_LU;
271   ierr = PetscMatlabEnginePut(PETSC_MATLAB_ENGINE_(A->comm),(PetscObject)A);CHKERRQ(ierr);
272   _A   = A->name;
273   ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(A->comm),"info_%s = struct('droptol',%g,'thresh',%g);",_A,info->dt,info->dtcol);CHKERRQ(ierr);
274   ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(A->comm),"[l_%s,u_%s,p_%s] = luinc(%s',info_%s);",_A,_A,_A,_A,_A);CHKERRQ(ierr);
275   ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(A->comm),"%s = 0;",_A);CHKERRQ(ierr);
276 
277   ierr = PetscStrlen(_A,&len);CHKERRQ(ierr);
278   ierr = PetscMalloc((len+2)*sizeof(char),&name);CHKERRQ(ierr);
279   sprintf(name,"_%s",_A);
280   ierr = PetscObjectSetName((PetscObject)*F,name);CHKERRQ(ierr);
281   ierr = PetscFree(name);CHKERRQ(ierr);
282   PetscFunctionReturn(0);
283 }
284 
285 #undef __FUNCT__
286 #define __FUNCT__ "MatFactorInfo_Matlab"
287 PetscErrorCode MatFactorInfo_Matlab(Mat A,PetscViewer viewer)
288 {
289   PetscErrorCode ierr;
290 
291   PetscFunctionBegin;
292   ierr = PetscViewerASCIIPrintf(viewer,"Matlab run parameters:  -- not written yet!\n");CHKERRQ(ierr);
293   PetscFunctionReturn(0);
294 }
295 
296 #undef __FUNCT__
297 #define __FUNCT__ "MatView_Matlab"
298 PetscErrorCode MatView_Matlab(Mat A,PetscViewer viewer)
299 {
300   PetscErrorCode    ierr;
301   PetscTruth        iascii;
302   PetscViewerFormat format;
303   Mat_Matlab        *lu=(Mat_Matlab*)(A->spptr);
304 
305   PetscFunctionBegin;
306   ierr = (*lu->MatView)(A,viewer);CHKERRQ(ierr);
307   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);CHKERRQ(ierr);
308   if (iascii) {
309     ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
310     if (format == PETSC_VIEWER_ASCII_FACTOR_INFO) {
311       ierr = MatFactorInfo_Matlab(A,viewer);
312     }
313   }
314   PetscFunctionReturn(0);
315 }
316 
317 #undef __FUNCT__
318 #define __FUNCT__ "MatDuplicate_Matlab"
319 PetscErrorCode MatDuplicate_Matlab(Mat A, MatDuplicateOption op, Mat *M)
320 {
321   PetscErrorCode ierr;
322   Mat_Matlab     *lu=(Mat_Matlab*)A->spptr;
323 
324   PetscFunctionBegin;
325   ierr = (*lu->MatDuplicate)(A,op,M);CHKERRQ(ierr);
326   ierr = PetscMemcpy((*M)->spptr,lu,sizeof(Mat_Matlab));CHKERRQ(ierr);
327   PetscFunctionReturn(0);
328 }
329 
330 EXTERN_C_BEGIN
331 #undef __FUNCT__
332 #define __FUNCT__ "MatConvert_SeqAIJ_Matlab"
333 PetscErrorCode PETSCMAT_DLLEXPORT MatConvert_SeqAIJ_Matlab(Mat A,MatType type,MatReuse reuse,Mat *newmat)
334 {
335   PetscErrorCode ierr;
336   Mat            B=*newmat;
337   Mat_Matlab     *lu;
338   PetscTruth     qr;
339 
340   PetscFunctionBegin;
341   if (reuse == MAT_INITIAL_MATRIX) {
342     ierr = MatDuplicate(A,MAT_COPY_VALUES,&B);CHKERRQ(ierr);
343   }
344 
345   ierr = PetscNewLog(B,Mat_Matlab,&lu);CHKERRQ(ierr);
346   lu->MatDuplicate         = A->ops->duplicate;
347   lu->MatView              = A->ops->view;
348   lu->MatLUFactorSymbolic  = A->ops->lufactorsymbolic;
349   lu->MatILUDTFactor       = A->ops->iludtfactor;
350   lu->MatDestroy           = A->ops->destroy;
351 
352   B->spptr                 = (void*)lu;
353   B->ops->duplicate        = MatDuplicate_Matlab;
354   B->ops->view             = MatView_Matlab;
355   B->ops->lufactorsymbolic = MatLUFactorSymbolic_Matlab;
356   B->ops->iludtfactor      = MatILUDTFactor_Matlab;
357   B->ops->destroy          = MatDestroy_Matlab;
358 
359   ierr = PetscOptionsHasName(A->prefix,"-mat_matlab_qr",&qr);CHKERRQ(ierr);
360   if (qr) {
361     B->ops->lufactorsymbolic = MatLUFactorSymbolic_Matlab_QR;
362     ierr = PetscInfo(0,"Using Matlab QR with iterative refinement for LU factorization and solves\n");CHKERRQ(ierr);
363   } else {
364     ierr = PetscInfo(0,"Using Matlab for LU factorizations and solves.\n");CHKERRQ(ierr);
365   }
366   ierr = PetscInfo(0,"Using Matlab for ILUDT factorizations and solves.\n");CHKERRQ(ierr);
367 
368   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqaij_matlab_C",
369                                            "MatConvert_SeqAIJ_Matlab",MatConvert_SeqAIJ_Matlab);CHKERRQ(ierr);
370   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_matlab_seqaij_C",
371                                            "MatConvert_Matlab_SeqAIJ",MatConvert_Matlab_SeqAIJ);CHKERRQ(ierr);
372   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"PetscMatlabEnginePut_C",
373                                            "MatMatlabEnginePut_Matlab",MatMatlabEnginePut_Matlab);CHKERRQ(ierr);
374   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"PetscMatlabEngineGet_C",
375                                            "MatMatlabEngineGet_Matlab",MatMatlabEngineGet_Matlab);CHKERRQ(ierr);
376   ierr = PetscObjectChangeTypeName((PetscObject)B,MATMATLAB);CHKERRQ(ierr);
377   *newmat = B;
378   PetscFunctionReturn(0);
379 }
380 EXTERN_C_END
381 
382 /*MC
383   MATMATLAB - MATMATLAB = "matlab" - A matrix type providing direct solvers (LU and QR) and drop tolerance
384   based ILU factorization (ILUDT) for sequential matrices via the external package Matlab.
385 
386   If Matlab is instaled (see the manual for
387   instructions on how to declare the existence of external packages),
388   a matrix type can be constructed which invokes Matlab solvers.
389   After calling MatCreate(...,A), simply call MatSetType(A,MATMATLAB).
390   This matrix type is only supported for double precision real.
391 
392   This matrix inherits from MATSEQAIJ.  As a result, MatSeqAIJSetPreallocation is
393   supported for this matrix type.  One can also call MatConvert for an inplace conversion to or from
394   the MATSEQAIJ type without data copy.
395 
396   Options Database Keys:
397 + -mat_type matlab - sets the matrix type to "matlab" during a call to MatSetFromOptions()
398 - -mat_matlab_qr   - sets the direct solver to be QR instead of LU
399 
400   Level: beginner
401 
402 .seealso: PCLU
403 M*/
404 
405 EXTERN_C_BEGIN
406 #undef __FUNCT__
407 #define __FUNCT__ "MatCreate_Matlab"
408 PetscErrorCode PETSCMAT_DLLEXPORT MatCreate_Matlab(Mat A)
409 {
410   PetscErrorCode ierr;
411 
412   PetscFunctionBegin;
413   ierr = MatSetType(A,MATSEQAIJ);CHKERRQ(ierr);
414   ierr = MatConvert_SeqAIJ_Matlab(A,MATMATLAB,MAT_REUSE_MATRIX,&A);CHKERRQ(ierr);
415   PetscFunctionReturn(0);
416 }
417 EXTERN_C_END
418