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