xref: /petsc/src/mat/impls/aij/seq/matlab/aijmatlab.c (revision f251bdbd1d9e8529587f82c093daf4686cd196a5)
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 = 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->m];
63   ierr  = PetscMalloc3(aij->nz,PetscScalar,&aij->a,aij->nz,PetscInt,&aij->j,mat->m+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->m+1)*sizeof(int));CHKERRQ(ierr);
71 
72   for (ii=0; ii<mat->m; 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   Mat_SeqAIJ     *f = (Mat_SeqAIJ*)(*F)->data;
155   PetscErrorCode ierr;
156   size_t         len;
157   char           *_A,*name;
158 
159   PetscFunctionBegin;
160   ierr = PetscMatlabEnginePut(PETSC_MATLAB_ENGINE_(A->comm),(PetscObject)A);CHKERRQ(ierr);
161   _A   = A->name;
162   ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(A->comm),"[l_%s,u_%s,p_%s] = lu(%s',%g);",_A,_A,_A,_A,info->dtcol);CHKERRQ(ierr);
163   ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(A->comm),"%s = 0;",_A);CHKERRQ(ierr);
164   ierr = PetscStrlen(_A,&len);CHKERRQ(ierr);
165   ierr = PetscMalloc((len+2)*sizeof(char),&name);CHKERRQ(ierr);
166   sprintf(name,"_%s",_A);
167   ierr = PetscObjectSetName((PetscObject)*F,name);CHKERRQ(ierr);
168   ierr = PetscFree(name);CHKERRQ(ierr);
169   PetscFunctionReturn(0);
170 }
171 
172 #undef __FUNCT__
173 #define __FUNCT__ "MatLUFactorSymbolic_Matlab"
174 PetscErrorCode MatLUFactorSymbolic_Matlab(Mat A,IS r,IS c,MatFactorInfo *info,Mat *F)
175 {
176   PetscErrorCode ierr;
177   Mat_SeqAIJ     *f;
178 
179   PetscFunctionBegin;
180   if (A->N != A->M) SETERRQ(PETSC_ERR_ARG_SIZ,"matrix must be square");
181   ierr                       = MatCreate(A->comm,F);CHKERRQ(ierr);
182   ierr                       = MatSetSizes(*F,A->m,A->n,A->m,A->n);CHKERRQ(ierr);
183   ierr                       = MatSetType(*F,A->type_name);CHKERRQ(ierr);
184   ierr                       = MatSeqAIJSetPreallocation(*F,0,PETSC_NULL);CHKERRQ(ierr);
185   (*F)->ops->solve           = MatSolve_Matlab;
186   (*F)->ops->lufactornumeric = MatLUFactorNumeric_Matlab;
187   (*F)->factor               = FACTOR_LU;
188   PetscFunctionReturn(0);
189 }
190 
191 /* ---------------------------------------------------------------------------------*/
192 #undef __FUNCT__
193 #define __FUNCT__ "MatSolve_Matlab_QR"
194 PetscErrorCode MatSolve_Matlab_QR(Mat A,Vec b,Vec x)
195 {
196   PetscErrorCode ierr;
197   const char     *_A,*_b,*_x;
198 
199   PetscFunctionBegin;
200   /* make sure objects have names; use default if not */
201   ierr = PetscObjectName((PetscObject)b);CHKERRQ(ierr);
202   ierr = PetscObjectName((PetscObject)x);CHKERRQ(ierr);
203 
204   ierr = PetscObjectGetName((PetscObject)A,&_A);CHKERRQ(ierr);
205   ierr = PetscObjectGetName((PetscObject)b,&_b);CHKERRQ(ierr);
206   ierr = PetscObjectGetName((PetscObject)x,&_x);CHKERRQ(ierr);
207   ierr = PetscMatlabEnginePut(PETSC_MATLAB_ENGINE_(A->comm),(PetscObject)b);CHKERRQ(ierr);
208   ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(A->comm),"%s = r%s\\(r%s'\\(%s*%s));",_x,_A,_A,_A+1,_b);CHKERRQ(ierr);
209   ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(A->comm),"%s = 0;",_b);CHKERRQ(ierr);
210   /* ierr = PetscMatlabEnginePrintOutput(PETSC_MATLAB_ENGINE_(A->comm),stdout);CHKERRQ(ierr);  */
211   ierr = PetscMatlabEngineGet(PETSC_MATLAB_ENGINE_(A->comm),(PetscObject)x);CHKERRQ(ierr);
212   PetscFunctionReturn(0);
213 }
214 
215 #undef __FUNCT__
216 #define __FUNCT__ "MatLUFactorNumeric_Matlab_QR"
217 PetscErrorCode MatLUFactorNumeric_Matlab_QR(Mat A,MatFactorInfo *info,Mat *F)
218 {
219   PetscErrorCode ierr;
220   size_t         len;
221   char           *_A,*name;
222 
223   PetscFunctionBegin;
224   ierr = PetscMatlabEnginePut(PETSC_MATLAB_ENGINE_(A->comm),(PetscObject)A);CHKERRQ(ierr);
225   _A   = A->name;
226   ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(A->comm),"r_%s = qr(%s');",_A,_A);CHKERRQ(ierr);
227   ierr = PetscStrlen(_A,&len);CHKERRQ(ierr);
228   ierr = PetscMalloc((len+2)*sizeof(char),&name);CHKERRQ(ierr);
229   sprintf(name,"_%s",_A);
230   ierr = PetscObjectSetName((PetscObject)*F,name);CHKERRQ(ierr);
231   ierr = PetscFree(name);CHKERRQ(ierr);
232   PetscFunctionReturn(0);
233 }
234 
235 #undef __FUNCT__
236 #define __FUNCT__ "MatLUFactorSymbolic_Matlab_QR"
237 PetscErrorCode MatLUFactorSymbolic_Matlab_QR(Mat A,IS r,IS c,MatFactorInfo *info,Mat *F)
238 {
239   PetscErrorCode ierr;
240 
241   PetscFunctionBegin;
242   if (A->N != A->M) SETERRQ(PETSC_ERR_ARG_SIZ,"matrix must be square");
243   ierr                       = MatCreate(A->comm,F);CHKERRQ(ierr);
244   ierr                       = MatSetSizes(*F,A->m,A->n,A->m,A->n);CHKERRQ(ierr);
245   ierr                       = MatSetType(*F,A->type_name);CHKERRQ(ierr);
246   ierr                       = MatSeqAIJSetPreallocation(*F,0,PETSC_NULL);CHKERRQ(ierr);
247   (*F)->ops->solve           = MatSolve_Matlab_QR;
248   (*F)->ops->lufactornumeric = MatLUFactorNumeric_Matlab_QR;
249   (*F)->factor               = FACTOR_LU;
250   (*F)->assembled            = PETSC_TRUE;  /* required by -ksp_view */
251 
252   PetscFunctionReturn(0);
253 }
254 
255 /* --------------------------------------------------------------------------------*/
256 #undef __FUNCT__
257 #define __FUNCT__ "MatILUDTFactor_Matlab"
258 PetscErrorCode MatILUDTFactor_Matlab(Mat A,IS isrow,IS iscol,MatFactorInfo *info,Mat *F)
259 {
260   PetscErrorCode ierr;
261   size_t         len;
262   char           *_A,*name;
263 
264   PetscFunctionBegin;
265   if (info->dt == PETSC_DEFAULT)      info->dt      = .005;
266   if (info->dtcol == PETSC_DEFAULT)   info->dtcol   = .01;
267   if (A->N != A->M) SETERRQ(PETSC_ERR_ARG_SIZ,"matrix must be square");
268   ierr                       = MatCreate(A->comm,F);CHKERRQ(ierr);
269   ierr                       = MatSetSizes(*F,A->m,A->n,A->m,A->n);CHKERRQ(ierr);
270   ierr                       = MatSetType(*F,A->type_name);CHKERRQ(ierr);
271   ierr                       = MatSeqAIJSetPreallocation(*F,0,PETSC_NULL);CHKERRQ(ierr);
272   (*F)->ops->solve           = MatSolve_Matlab;
273   (*F)->factor               = FACTOR_LU;
274   ierr = PetscMatlabEnginePut(PETSC_MATLAB_ENGINE_(A->comm),(PetscObject)A);CHKERRQ(ierr);
275   _A   = A->name;
276   ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(A->comm),"info_%s = struct('droptol',%g,'thresh',%g);",_A,info->dt,info->dtcol);CHKERRQ(ierr);
277   ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(A->comm),"[l_%s,u_%s,p_%s] = luinc(%s',info_%s);",_A,_A,_A,_A,_A);CHKERRQ(ierr);
278   ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(A->comm),"%s = 0;",_A);CHKERRQ(ierr);
279 
280   ierr = PetscStrlen(_A,&len);CHKERRQ(ierr);
281   ierr = PetscMalloc((len+2)*sizeof(char),&name);CHKERRQ(ierr);
282   sprintf(name,"_%s",_A);
283   ierr = PetscObjectSetName((PetscObject)*F,name);CHKERRQ(ierr);
284   ierr = PetscFree(name);CHKERRQ(ierr);
285   PetscFunctionReturn(0);
286 }
287 
288 #undef __FUNCT__
289 #define __FUNCT__ "MatFactorInfo_Matlab"
290 PetscErrorCode MatFactorInfo_Matlab(Mat A,PetscViewer viewer)
291 {
292   PetscErrorCode ierr;
293 
294   PetscFunctionBegin;
295   ierr = PetscViewerASCIIPrintf(viewer,"Matlab run parameters:  -- not written yet!\n");CHKERRQ(ierr);
296   PetscFunctionReturn(0);
297 }
298 
299 #undef __FUNCT__
300 #define __FUNCT__ "MatView_Matlab"
301 PetscErrorCode MatView_Matlab(Mat A,PetscViewer viewer)
302 {
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 {
324   PetscErrorCode ierr;
325   Mat_Matlab     *lu=(Mat_Matlab*)A->spptr;
326 
327   PetscFunctionBegin;
328   ierr = (*lu->MatDuplicate)(A,op,M);CHKERRQ(ierr);
329   ierr = PetscMemcpy((*M)->spptr,lu,sizeof(Mat_Matlab));CHKERRQ(ierr);
330   PetscFunctionReturn(0);
331 }
332 
333 EXTERN_C_BEGIN
334 #undef __FUNCT__
335 #define __FUNCT__ "MatConvert_SeqAIJ_Matlab"
336 PetscErrorCode PETSCMAT_DLLEXPORT MatConvert_SeqAIJ_Matlab(Mat A,MatType type,MatReuse reuse,Mat *newmat)
337 {
338   /* This routine is only called to convert to MATMATLAB */
339   /* from MATSEQAIJ, so we will ignore 'MatType type'. */
340   PetscErrorCode ierr;
341   Mat            B=*newmat;
342   Mat_Matlab     *lu;
343   PetscTruth     qr;
344 
345   PetscFunctionBegin;
346   if (reuse == MAT_INITIAL_MATRIX) {
347     ierr = MatDuplicate(A,MAT_COPY_VALUES,&B);CHKERRQ(ierr);
348   }
349 
350   ierr = PetscNew(Mat_Matlab,&lu);CHKERRQ(ierr);
351   lu->MatDuplicate         = A->ops->duplicate;
352   lu->MatView              = A->ops->view;
353   lu->MatLUFactorSymbolic  = A->ops->lufactorsymbolic;
354   lu->MatILUDTFactor       = A->ops->iludtfactor;
355   lu->MatDestroy           = A->ops->destroy;
356 
357   B->spptr                 = (void*)lu;
358   B->ops->duplicate        = MatDuplicate_Matlab;
359   B->ops->view             = MatView_Matlab;
360   B->ops->lufactorsymbolic = MatLUFactorSymbolic_Matlab;
361   B->ops->iludtfactor      = MatILUDTFactor_Matlab;
362   B->ops->destroy          = MatDestroy_Matlab;
363 
364   ierr = PetscOptionsHasName(A->prefix,"-mat_matlab_qr",&qr);CHKERRQ(ierr);
365   if (qr) {
366     B->ops->lufactorsymbolic = MatLUFactorSymbolic_Matlab_QR;
367     ierr = PetscLogInfo((0,"MatConvert_SeqAIJ_Matlab:Using Matlab QR with iterative refinement for LU factorization and solves\n"));CHKERRQ(ierr);
368   } else {
369     ierr = PetscLogInfo((0,"MatConvert_SeqAIJ_Matlab:Using Matlab for LU factorizations and solves.\n"));CHKERRQ(ierr);
370   }
371   ierr = PetscLogInfo((0,"MatConvert_SeqAIJ_Matlab:Using Matlab for ILUDT factorizations and solves.\n"));CHKERRQ(ierr);
372 
373   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqaij_matlab_C",
374                                            "MatConvert_SeqAIJ_Matlab",MatConvert_SeqAIJ_Matlab);CHKERRQ(ierr);
375   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_matlab_seqaij_C",
376                                            "MatConvert_Matlab_SeqAIJ",MatConvert_Matlab_SeqAIJ);CHKERRQ(ierr);
377   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"PetscMatlabEnginePut_C",
378                                            "MatMatlabEnginePut_Matlab",MatMatlabEnginePut_Matlab);CHKERRQ(ierr);
379   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"PetscMatlabEngineGet_C",
380                                            "MatMatlabEngineGet_Matlab",MatMatlabEngineGet_Matlab);CHKERRQ(ierr);
381   ierr = PetscObjectChangeTypeName((PetscObject)B,MATMATLAB);CHKERRQ(ierr);
382   *newmat = B;
383   PetscFunctionReturn(0);
384 }
385 EXTERN_C_END
386 
387 /*MC
388   MATMATLAB - MATMATLAB = "matlab" - A matrix type providing direct solvers (LU and QR) and drop tolerance
389   based ILU factorization (ILUDT) for sequential matrices via the external package Matlab.
390 
391   If Matlab is instaled (see the manual for
392   instructions on how to declare the existence of external packages),
393   a matrix type can be constructed which invokes Matlab solvers.
394   After calling MatCreate(...,A), simply call MatSetType(A,MATMATLAB).
395   This matrix type is only supported for double precision real.
396 
397   This matrix inherits from MATSEQAIJ.  As a result, MatSeqAIJSetPreallocation is
398   supported for this matrix type.  One can also call MatConvert for an inplace conversion to or from
399   the MATSEQAIJ type without data copy.
400 
401   Options Database Keys:
402 + -mat_type matlab - sets the matrix type to "matlab" during a call to MatSetFromOptions()
403 - -mat_matlab_qr   - sets the direct solver to be QR instead of LU
404 
405   Level: beginner
406 
407 .seealso: PCLU
408 M*/
409 
410 EXTERN_C_BEGIN
411 #undef __FUNCT__
412 #define __FUNCT__ "MatCreate_Matlab"
413 PetscErrorCode PETSCMAT_DLLEXPORT MatCreate_Matlab(Mat A)
414 {
415   PetscErrorCode ierr;
416 
417   PetscFunctionBegin;
418   ierr = PetscObjectChangeTypeName((PetscObject)A,MATMATLAB);CHKERRQ(ierr);
419   ierr = MatSetType(A,MATSEQAIJ);CHKERRQ(ierr);
420   ierr = MatConvert_SeqAIJ_Matlab(A,MATMATLAB,MAT_REUSE_MATRIX,&A);CHKERRQ(ierr);
421   PetscFunctionReturn(0);
422 }
423 EXTERN_C_END
424