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