xref: /petsc/src/mat/impls/aij/seq/matlab/aijmatlab.c (revision df48e8d96c19df54efdde2c76f874a16fcafd8fe)
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,const 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,&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   f                          = (Mat_SeqAIJ*)(*F)->data;
189   f->lu_dtcol = info->dtcol;
190   PetscFunctionReturn(0);
191 }
192 
193 /* ---------------------------------------------------------------------------------*/
194 #undef __FUNCT__
195 #define __FUNCT__ "MatSolve_Matlab_QR"
196 PetscErrorCode MatSolve_Matlab_QR(Mat A,Vec b,Vec x)
197 {
198   PetscErrorCode ierr;
199   const char     *_A,*_b,*_x;
200 
201   PetscFunctionBegin;
202   /* make sure objects have names; use default if not */
203   ierr = PetscObjectName((PetscObject)b);CHKERRQ(ierr);
204   ierr = PetscObjectName((PetscObject)x);CHKERRQ(ierr);
205 
206   ierr = PetscObjectGetName((PetscObject)A,&_A);CHKERRQ(ierr);
207   ierr = PetscObjectGetName((PetscObject)b,&_b);CHKERRQ(ierr);
208   ierr = PetscObjectGetName((PetscObject)x,&_x);CHKERRQ(ierr);
209   ierr = PetscMatlabEnginePut(PETSC_MATLAB_ENGINE_(A->comm),(PetscObject)b);CHKERRQ(ierr);
210   ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(A->comm),"%s = r%s\\(r%s'\\(%s*%s));",_x,_A,_A,_A+1,_b);CHKERRQ(ierr);
211   ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(A->comm),"%s = 0;",_b);CHKERRQ(ierr);
212   /* ierr = PetscMatlabEnginePrintOutput(PETSC_MATLAB_ENGINE_(A->comm),stdout);CHKERRQ(ierr);  */
213   ierr = PetscMatlabEngineGet(PETSC_MATLAB_ENGINE_(A->comm),(PetscObject)x);CHKERRQ(ierr);
214   PetscFunctionReturn(0);
215 }
216 
217 #undef __FUNCT__
218 #define __FUNCT__ "MatLUFactorNumeric_Matlab_QR"
219 PetscErrorCode MatLUFactorNumeric_Matlab_QR(Mat A,MatFactorInfo *info,Mat *F)
220 {
221   PetscErrorCode ierr;
222   size_t          len;
223   char            *_A,*name;
224 
225   PetscFunctionBegin;
226   ierr = PetscMatlabEnginePut(PETSC_MATLAB_ENGINE_(A->comm),(PetscObject)A);CHKERRQ(ierr);
227   _A   = A->name;
228   ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(A->comm),"r_%s = qr(%s');",_A,_A);CHKERRQ(ierr);
229   ierr = PetscStrlen(_A,&len);CHKERRQ(ierr);
230   ierr = PetscMalloc((len+2)*sizeof(char),&name);CHKERRQ(ierr);
231   sprintf(name,"_%s",_A);
232   ierr = PetscObjectSetName((PetscObject)*F,name);CHKERRQ(ierr);
233   ierr = PetscFree(name);CHKERRQ(ierr);
234   PetscFunctionReturn(0);
235 }
236 
237 #undef __FUNCT__
238 #define __FUNCT__ "MatLUFactorSymbolic_Matlab_QR"
239 PetscErrorCode MatLUFactorSymbolic_Matlab_QR(Mat A,IS r,IS c,MatFactorInfo *info,Mat *F)
240 {
241   PetscErrorCode ierr;
242 
243   PetscFunctionBegin;
244   if (A->N != A->M) SETERRQ(PETSC_ERR_ARG_SIZ,"matrix must be square");
245   ierr                       = MatCreate(A->comm,F);CHKERRQ(ierr);
246   ierr                       = MatSetSizes(*F,A->m,A->n,A->m,A->n);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,F);CHKERRQ(ierr);
271   ierr                       = MatSetSizes(*F,A->m,A->n,A->m,A->n);CHKERRQ(ierr);
272   ierr                       = MatSetType(*F,A->type_name);CHKERRQ(ierr);
273   ierr                       = MatSeqAIJSetPreallocation(*F,0,PETSC_NULL);CHKERRQ(ierr);
274   (*F)->ops->solve           = MatSolve_Matlab;
275   (*F)->factor               = FACTOR_LU;
276   ierr = PetscMatlabEnginePut(PETSC_MATLAB_ENGINE_(A->comm),(PetscObject)A);CHKERRQ(ierr);
277   _A   = A->name;
278   ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(A->comm),"info_%s = struct('droptol',%g,'thresh',%g);",_A,info->dt,info->dtcol);CHKERRQ(ierr);
279   ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(A->comm),"[l_%s,u_%s,p_%s] = luinc(%s',info_%s);",_A,_A,_A,_A,_A);CHKERRQ(ierr);
280   ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(A->comm),"%s = 0;",_A);CHKERRQ(ierr);
281 
282   ierr = PetscStrlen(_A,&len);CHKERRQ(ierr);
283   ierr = PetscMalloc((len+2)*sizeof(char),&name);CHKERRQ(ierr);
284   sprintf(name,"_%s",_A);
285   ierr = PetscObjectSetName((PetscObject)*F,name);CHKERRQ(ierr);
286   ierr = PetscFree(name);CHKERRQ(ierr);
287   PetscFunctionReturn(0);
288 }
289 
290 #undef __FUNCT__
291 #define __FUNCT__ "MatFactorInfo_Matlab"
292 PetscErrorCode MatFactorInfo_Matlab(Mat A,PetscViewer viewer)
293 {
294   PetscErrorCode ierr;
295 
296   PetscFunctionBegin;
297   ierr = PetscViewerASCIIPrintf(viewer,"Matlab run parameters:  -- not written yet!\n");CHKERRQ(ierr);
298   PetscFunctionReturn(0);
299 }
300 
301 #undef __FUNCT__
302 #define __FUNCT__ "MatView_Matlab"
303 PetscErrorCode MatView_Matlab(Mat A,PetscViewer viewer) {
304   PetscErrorCode    ierr;
305   PetscTruth        iascii;
306   PetscViewerFormat format;
307   Mat_Matlab        *lu=(Mat_Matlab*)(A->spptr);
308 
309   PetscFunctionBegin;
310   ierr = (*lu->MatView)(A,viewer);CHKERRQ(ierr);
311   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);CHKERRQ(ierr);
312   if (iascii) {
313     ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
314     if (format == PETSC_VIEWER_ASCII_FACTOR_INFO) {
315       ierr = MatFactorInfo_Matlab(A,viewer);
316     }
317   }
318   PetscFunctionReturn(0);
319 }
320 
321 #undef __FUNCT__
322 #define __FUNCT__ "MatDuplicate_Matlab"
323 PetscErrorCode MatDuplicate_Matlab(Mat A, MatDuplicateOption op, Mat *M) {
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,const 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