xref: /petsc/src/mat/impls/aij/seq/matlab/aijmatlab.c (revision 7529efd4b68aedd45db7642b3ca14a621048ee72)
13b3e256bSKris Buschelman /*
23b3e256bSKris Buschelman         Provides an interface for the Matlab engine sparse solver
33b3e256bSKris Buschelman 
43b3e256bSKris Buschelman */
53b3e256bSKris Buschelman #include "src/mat/impls/aij/seq/aij.h"
63b3e256bSKris Buschelman 
73b3e256bSKris Buschelman #include "engine.h"   /* Matlab include file */
83b3e256bSKris Buschelman #include "mex.h"      /* Matlab include file */
93b3e256bSKris Buschelman 
1005db81ecSKris Buschelman typedef struct {
116849ba73SBarry Smith   PetscErrorCode (*MatDuplicate)(Mat,MatDuplicateOption,Mat*);
126849ba73SBarry Smith   PetscErrorCode (*MatView)(Mat,PetscViewer);
136849ba73SBarry Smith   PetscErrorCode (*MatLUFactorSymbolic)(Mat,IS,IS,MatFactorInfo*,Mat*);
14*7529efd4SKris Buschelman   PetscErrorCode (*MatILUDTFactor)(Mat,IS,IS,MatFactorInfo*,Mat*);
156849ba73SBarry Smith   PetscErrorCode (*MatDestroy)(Mat);
1605db81ecSKris Buschelman } Mat_Matlab;
1705db81ecSKris Buschelman 
18a1d52234SKris Buschelman 
19a1d52234SKris Buschelman EXTERN_C_BEGIN
20a1d52234SKris Buschelman #undef __FUNCT__
21a1d52234SKris Buschelman #define __FUNCT__ "MatMatlabEnginePut_Matlab"
22dfbe8321SBarry Smith PetscErrorCode MatMatlabEnginePut_Matlab(PetscObject obj,void *mengine)
23a1d52234SKris Buschelman {
24dfbe8321SBarry Smith   PetscErrorCode ierr;
25a1d52234SKris Buschelman   Mat         B = (Mat)obj;
26a1d52234SKris Buschelman   mxArray     *mat;
27a1d52234SKris Buschelman   Mat_SeqAIJ  *aij = (Mat_SeqAIJ*)B->data;
28a1d52234SKris Buschelman 
29a1d52234SKris Buschelman   PetscFunctionBegin;
30a1d52234SKris Buschelman   mat  = mxCreateSparse(B->n,B->m,aij->nz,mxREAL);
31a1d52234SKris Buschelman   ierr = PetscMemcpy(mxGetPr(mat),aij->a,aij->nz*sizeof(PetscScalar));CHKERRQ(ierr);
32a1d52234SKris Buschelman   /* Matlab stores by column, not row so we pass in the transpose of the matrix */
33a1d52234SKris Buschelman   ierr = PetscMemcpy(mxGetIr(mat),aij->j,aij->nz*sizeof(int));CHKERRQ(ierr);
34a1d52234SKris Buschelman   ierr = PetscMemcpy(mxGetJc(mat),aij->i,(B->m+1)*sizeof(int));CHKERRQ(ierr);
35a1d52234SKris Buschelman 
36a1d52234SKris Buschelman   /* Matlab indices start at 0 for sparse (what a surprise) */
37a1d52234SKris Buschelman 
38a1d52234SKris Buschelman   ierr = PetscObjectName(obj);CHKERRQ(ierr);
39a1d52234SKris Buschelman   engPutVariable((Engine *)mengine,obj->name,mat);
40a1d52234SKris Buschelman   PetscFunctionReturn(0);
41a1d52234SKris Buschelman }
42a1d52234SKris Buschelman EXTERN_C_END
43a1d52234SKris Buschelman 
44a1d52234SKris Buschelman EXTERN_C_BEGIN
45a1d52234SKris Buschelman #undef __FUNCT__
46a1d52234SKris Buschelman #define __FUNCT__ "MatMatlabEngineGet_Matlab"
47dfbe8321SBarry Smith PetscErrorCode MatMatlabEngineGet_Matlab(PetscObject obj,void *mengine)
48a1d52234SKris Buschelman {
49dfbe8321SBarry Smith   PetscErrorCode ierr;
50dfbe8321SBarry Smith   int        ii;
51a1d52234SKris Buschelman   Mat        mat = (Mat)obj;
52a1d52234SKris Buschelman   Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data;
53a1d52234SKris Buschelman   mxArray    *mmat;
54a1d52234SKris Buschelman 
55a1d52234SKris Buschelman   PetscFunctionBegin;
56a1d52234SKris Buschelman   ierr = PetscFree(aij->a);CHKERRQ(ierr);
57a1d52234SKris Buschelman 
58a1d52234SKris Buschelman   mmat = engGetVariable((Engine *)mengine,obj->name);
59a1d52234SKris Buschelman 
60a1d52234SKris Buschelman   aij->nz           = (mxGetJc(mmat))[mat->m];
61a1d52234SKris Buschelman   ierr              = PetscMalloc(((size_t) aij->nz)*(sizeof(int)+sizeof(PetscScalar))+(mat->m+1)*sizeof(int),&aij->a);CHKERRQ(ierr);
62a1d52234SKris Buschelman   aij->j            = (int*)(aij->a + aij->nz);
63a1d52234SKris Buschelman   aij->i            = aij->j + aij->nz;
64a1d52234SKris Buschelman   aij->singlemalloc = PETSC_TRUE;
65a1d52234SKris Buschelman   aij->freedata     = PETSC_TRUE;
66a1d52234SKris Buschelman 
67a1d52234SKris Buschelman   ierr = PetscMemcpy(aij->a,mxGetPr(mmat),aij->nz*sizeof(PetscScalar));CHKERRQ(ierr);
68a1d52234SKris Buschelman   /* Matlab stores by column, not row so we pass in the transpose of the matrix */
69a1d52234SKris Buschelman   ierr = PetscMemcpy(aij->j,mxGetIr(mmat),aij->nz*sizeof(int));CHKERRQ(ierr);
70a1d52234SKris Buschelman   ierr = PetscMemcpy(aij->i,mxGetJc(mmat),(mat->m+1)*sizeof(int));CHKERRQ(ierr);
71a1d52234SKris Buschelman 
72a1d52234SKris Buschelman   for (ii=0; ii<mat->m; ii++) {
73a1d52234SKris Buschelman     aij->ilen[ii] = aij->imax[ii] = aij->i[ii+1] - aij->i[ii];
74a1d52234SKris Buschelman   }
75a1d52234SKris Buschelman 
76a1d52234SKris Buschelman   ierr = MatAssemblyBegin(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
77a1d52234SKris Buschelman   ierr = MatAssemblyEnd(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
78a1d52234SKris Buschelman 
79a1d52234SKris Buschelman   PetscFunctionReturn(0);
80a1d52234SKris Buschelman }
81a1d52234SKris Buschelman EXTERN_C_END
82a1d52234SKris Buschelman 
8305db81ecSKris Buschelman EXTERN_C_BEGIN
843b3e256bSKris Buschelman #undef __FUNCT__
8505db81ecSKris Buschelman #define __FUNCT__ "MatConvert_Matlab_SeqAIJ"
86ceb03754SKris Buschelman PetscErrorCode MatConvert_Matlab_SeqAIJ(Mat A,const MatType type,MatReuse reuse,Mat *newmat)
87521d7252SBarry Smith {
88dfbe8321SBarry Smith   PetscErrorCode ierr;
8905db81ecSKris Buschelman   Mat            B=*newmat;
9005db81ecSKris Buschelman   Mat_Matlab    *lu=(Mat_Matlab*)A->spptr;
9105db81ecSKris Buschelman 
9205db81ecSKris Buschelman   PetscFunctionBegin;
93ceb03754SKris Buschelman   if (reuse == MAT_INITIAL_MATRIX) {
9405db81ecSKris Buschelman     ierr = MatDuplicate(A,MAT_COPY_VALUES,&B);CHKERRQ(ierr);
9505db81ecSKris Buschelman   }
96901853e0SKris Buschelman   B->ops->duplicate        = lu->MatDuplicate;
97901853e0SKris Buschelman   B->ops->view             = lu->MatView;
98901853e0SKris Buschelman   B->ops->lufactorsymbolic = lu->MatLUFactorSymbolic;
99901853e0SKris Buschelman   B->ops->iludtfactor      = lu->MatILUDTFactor;
100901853e0SKris Buschelman   B->ops->destroy          = lu->MatDestroy;
10105db81ecSKris Buschelman 
10205db81ecSKris Buschelman   ierr = PetscFree(lu);CHKERRQ(ierr);
103901853e0SKris Buschelman 
104901853e0SKris Buschelman   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_matlab_C","",PETSC_NULL);CHKERRQ(ierr);
105901853e0SKris Buschelman   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_matlab_seqaij_C","",PETSC_NULL);CHKERRQ(ierr);
106901853e0SKris Buschelman   ierr = PetscObjectComposeFunction((PetscObject)B,"PetscMatlabEnginePut_C","",PETSC_NULL);CHKERRQ(ierr);
107901853e0SKris Buschelman   ierr = PetscObjectComposeFunction((PetscObject)B,"PetscMatlabEngineGet_C","",PETSC_NULL);CHKERRQ(ierr);
108901853e0SKris Buschelman 
10905db81ecSKris Buschelman   ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr);
11005db81ecSKris Buschelman   *newmat = B;
11105db81ecSKris Buschelman   PetscFunctionReturn(0);
11205db81ecSKris Buschelman }
11305db81ecSKris Buschelman EXTERN_C_END
11405db81ecSKris Buschelman 
11505db81ecSKris Buschelman #undef __FUNCT__
11605db81ecSKris Buschelman #define __FUNCT__ "MatDestroy_Matlab"
117dfbe8321SBarry Smith PetscErrorCode MatDestroy_Matlab(Mat A)
118dfbe8321SBarry Smith {
119dfbe8321SBarry Smith   PetscErrorCode ierr;
12005db81ecSKris Buschelman 
12105db81ecSKris Buschelman   PetscFunctionBegin;
12205db81ecSKris Buschelman   ierr = MatConvert_Matlab_SeqAIJ(A,MATSEQAIJ,&A);CHKERRQ(ierr);
12305db81ecSKris Buschelman   ierr = (*A->ops->destroy)(A);CHKERRQ(ierr);
12405db81ecSKris Buschelman   PetscFunctionReturn(0);
12505db81ecSKris Buschelman }
12605db81ecSKris Buschelman 
12705db81ecSKris Buschelman #undef __FUNCT__
12805db81ecSKris Buschelman #define __FUNCT__ "MatSolve_Matlab"
129dfbe8321SBarry Smith PetscErrorCode MatSolve_Matlab(Mat A,Vec b,Vec x)
1303b3e256bSKris Buschelman {
131dfbe8321SBarry Smith   PetscErrorCode ierr;
1323b3e256bSKris Buschelman   char            *_A,*_b,*_x;
1333b3e256bSKris Buschelman 
1343b3e256bSKris Buschelman   PetscFunctionBegin;
1353b3e256bSKris Buschelman   /* make sure objects have names; use default if not */
1363b3e256bSKris Buschelman   ierr = PetscObjectName((PetscObject)b);CHKERRQ(ierr);
1373b3e256bSKris Buschelman   ierr = PetscObjectName((PetscObject)x);CHKERRQ(ierr);
1383b3e256bSKris Buschelman 
1393b3e256bSKris Buschelman   ierr = PetscObjectGetName((PetscObject)A,&_A);CHKERRQ(ierr);
1403b3e256bSKris Buschelman   ierr = PetscObjectGetName((PetscObject)b,&_b);CHKERRQ(ierr);
1413b3e256bSKris Buschelman   ierr = PetscObjectGetName((PetscObject)x,&_x);CHKERRQ(ierr);
1423b3e256bSKris Buschelman   ierr = PetscMatlabEnginePut(PETSC_MATLAB_ENGINE_(A->comm),(PetscObject)b);CHKERRQ(ierr);
1433b3e256bSKris Buschelman   ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(A->comm),"%s = u%s\\(l%s\\(p%s*%s));",_x,_A,_A,_A,_b);CHKERRQ(ierr);
1443b3e256bSKris Buschelman   ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(A->comm),"%s = 0;",_b);CHKERRQ(ierr);
1453b3e256bSKris Buschelman   /* ierr = PetscMatlabEnginePrintOutput(PETSC_MATLAB_ENGINE_(A->comm),stdout);CHKERRQ(ierr);  */
1463b3e256bSKris Buschelman   ierr = PetscMatlabEngineGet(PETSC_MATLAB_ENGINE_(A->comm),(PetscObject)x);CHKERRQ(ierr);
1473b3e256bSKris Buschelman   PetscFunctionReturn(0);
1483b3e256bSKris Buschelman }
1493b3e256bSKris Buschelman 
1503b3e256bSKris Buschelman #undef __FUNCT__
15105db81ecSKris Buschelman #define __FUNCT__ "MatLUFactorNumeric_Matlab"
152af281ebdSHong Zhang PetscErrorCode MatLUFactorNumeric_Matlab(Mat A,MatFactorInfo *info,Mat *F)
1533b3e256bSKris Buschelman {
1543b3e256bSKris Buschelman   Mat_SeqAIJ      *f = (Mat_SeqAIJ*)(*F)->data;
155dfbe8321SBarry Smith   PetscErrorCode ierr;
156de4209c5SBarry Smith   size_t          len;
1573b3e256bSKris Buschelman   char            *_A,*name;
1583b3e256bSKris Buschelman 
1593b3e256bSKris Buschelman   PetscFunctionBegin;
1603b3e256bSKris Buschelman   ierr = PetscMatlabEnginePut(PETSC_MATLAB_ENGINE_(A->comm),(PetscObject)A);CHKERRQ(ierr);
1613b3e256bSKris Buschelman   _A   = A->name;
1623b3e256bSKris Buschelman   ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(A->comm),"[l_%s,u_%s,p_%s] = lu(%s',%g);",_A,_A,_A,_A,f->lu_dtcol);CHKERRQ(ierr);
1633b3e256bSKris Buschelman   ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(A->comm),"%s = 0;",_A);CHKERRQ(ierr);
1643b3e256bSKris Buschelman   ierr = PetscStrlen(_A,&len);CHKERRQ(ierr);
1653b3e256bSKris Buschelman   ierr = PetscMalloc((len+2)*sizeof(char),&name);CHKERRQ(ierr);
1663b3e256bSKris Buschelman   sprintf(name,"_%s",_A);
1673b3e256bSKris Buschelman   ierr = PetscObjectSetName((PetscObject)*F,name);CHKERRQ(ierr);
1683b3e256bSKris Buschelman   ierr = PetscFree(name);CHKERRQ(ierr);
1693b3e256bSKris Buschelman   PetscFunctionReturn(0);
1703b3e256bSKris Buschelman }
1713b3e256bSKris Buschelman 
1723b3e256bSKris Buschelman #undef __FUNCT__
17305db81ecSKris Buschelman #define __FUNCT__ "MatLUFactorSymbolic_Matlab"
174dfbe8321SBarry Smith PetscErrorCode MatLUFactorSymbolic_Matlab(Mat A,IS r,IS c,MatFactorInfo *info,Mat *F)
1753b3e256bSKris Buschelman {
176dfbe8321SBarry Smith   PetscErrorCode ierr;
1773b3e256bSKris Buschelman   Mat_SeqAIJ *f;
1783b3e256bSKris Buschelman 
1793b3e256bSKris Buschelman   PetscFunctionBegin;
1803b3e256bSKris Buschelman   if (A->N != A->M) SETERRQ(PETSC_ERR_ARG_SIZ,"matrix must be square");
1813b3e256bSKris Buschelman   ierr                       = MatCreate(A->comm,A->m,A->n,A->m,A->n,F);CHKERRQ(ierr);
1823b3e256bSKris Buschelman   ierr                       = MatSetType(*F,A->type_name);CHKERRQ(ierr);
1833b3e256bSKris Buschelman   ierr                       = MatSeqAIJSetPreallocation(*F,0,PETSC_NULL);CHKERRQ(ierr);
18405db81ecSKris Buschelman   (*F)->ops->solve           = MatSolve_Matlab;
18505db81ecSKris Buschelman   (*F)->ops->lufactornumeric = MatLUFactorNumeric_Matlab;
1863b3e256bSKris Buschelman   (*F)->factor               = FACTOR_LU;
1873b3e256bSKris Buschelman   f                          = (Mat_SeqAIJ*)(*F)->data;
1883b3e256bSKris Buschelman   f->lu_dtcol = info->dtcol;
1893b3e256bSKris Buschelman   PetscFunctionReturn(0);
1903b3e256bSKris Buschelman }
1913b3e256bSKris Buschelman 
1923b3e256bSKris Buschelman /* ---------------------------------------------------------------------------------*/
1933b3e256bSKris Buschelman #undef __FUNCT__
19405db81ecSKris Buschelman #define __FUNCT__ "MatSolve_Matlab_QR"
195dfbe8321SBarry Smith PetscErrorCode MatSolve_Matlab_QR(Mat A,Vec b,Vec x)
1963b3e256bSKris Buschelman {
197dfbe8321SBarry Smith   PetscErrorCode ierr;
1983b3e256bSKris Buschelman   char            *_A,*_b,*_x;
1993b3e256bSKris Buschelman 
2003b3e256bSKris Buschelman   PetscFunctionBegin;
2013b3e256bSKris Buschelman   /* make sure objects have names; use default if not */
2023b3e256bSKris Buschelman   ierr = PetscObjectName((PetscObject)b);CHKERRQ(ierr);
2033b3e256bSKris Buschelman   ierr = PetscObjectName((PetscObject)x);CHKERRQ(ierr);
2043b3e256bSKris Buschelman 
2053b3e256bSKris Buschelman   ierr = PetscObjectGetName((PetscObject)A,&_A);CHKERRQ(ierr);
2063b3e256bSKris Buschelman   ierr = PetscObjectGetName((PetscObject)b,&_b);CHKERRQ(ierr);
2073b3e256bSKris Buschelman   ierr = PetscObjectGetName((PetscObject)x,&_x);CHKERRQ(ierr);
2083b3e256bSKris Buschelman   ierr = PetscMatlabEnginePut(PETSC_MATLAB_ENGINE_(A->comm),(PetscObject)b);CHKERRQ(ierr);
2093b3e256bSKris Buschelman   ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(A->comm),"%s = r%s\\(r%s'\\(%s*%s));",_x,_A,_A,_A+1,_b);CHKERRQ(ierr);
2103b3e256bSKris Buschelman   ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(A->comm),"%s = 0;",_b);CHKERRQ(ierr);
2113b3e256bSKris Buschelman   /* ierr = PetscMatlabEnginePrintOutput(PETSC_MATLAB_ENGINE_(A->comm),stdout);CHKERRQ(ierr);  */
2123b3e256bSKris Buschelman   ierr = PetscMatlabEngineGet(PETSC_MATLAB_ENGINE_(A->comm),(PetscObject)x);CHKERRQ(ierr);
2133b3e256bSKris Buschelman   PetscFunctionReturn(0);
2143b3e256bSKris Buschelman }
2153b3e256bSKris Buschelman 
2163b3e256bSKris Buschelman #undef __FUNCT__
21705db81ecSKris Buschelman #define __FUNCT__ "MatLUFactorNumeric_Matlab_QR"
218af281ebdSHong Zhang PetscErrorCode MatLUFactorNumeric_Matlab_QR(Mat A,MatFactorInfo *info,Mat *F)
2193b3e256bSKris Buschelman {
220dfbe8321SBarry Smith   PetscErrorCode ierr;
221de4209c5SBarry Smith   size_t          len;
2223b3e256bSKris Buschelman   char            *_A,*name;
2233b3e256bSKris Buschelman 
2243b3e256bSKris Buschelman   PetscFunctionBegin;
2253b3e256bSKris Buschelman   ierr = PetscMatlabEnginePut(PETSC_MATLAB_ENGINE_(A->comm),(PetscObject)A);CHKERRQ(ierr);
2263b3e256bSKris Buschelman   _A   = A->name;
2273b3e256bSKris Buschelman   ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(A->comm),"r_%s = qr(%s');",_A,_A);CHKERRQ(ierr);
2283b3e256bSKris Buschelman   ierr = PetscStrlen(_A,&len);CHKERRQ(ierr);
2293b3e256bSKris Buschelman   ierr = PetscMalloc((len+2)*sizeof(char),&name);CHKERRQ(ierr);
2303b3e256bSKris Buschelman   sprintf(name,"_%s",_A);
2313b3e256bSKris Buschelman   ierr = PetscObjectSetName((PetscObject)*F,name);CHKERRQ(ierr);
2323b3e256bSKris Buschelman   ierr = PetscFree(name);CHKERRQ(ierr);
2333b3e256bSKris Buschelman   PetscFunctionReturn(0);
2343b3e256bSKris Buschelman }
2353b3e256bSKris Buschelman 
2363b3e256bSKris Buschelman #undef __FUNCT__
23705db81ecSKris Buschelman #define __FUNCT__ "MatLUFactorSymbolic_Matlab_QR"
238dfbe8321SBarry Smith PetscErrorCode MatLUFactorSymbolic_Matlab_QR(Mat A,IS r,IS c,MatFactorInfo *info,Mat *F)
2393b3e256bSKris Buschelman {
240dfbe8321SBarry Smith   PetscErrorCode ierr;
2413b3e256bSKris Buschelman 
2423b3e256bSKris Buschelman   PetscFunctionBegin;
2433b3e256bSKris Buschelman   if (A->N != A->M) SETERRQ(PETSC_ERR_ARG_SIZ,"matrix must be square");
2443b3e256bSKris Buschelman   ierr                       = MatCreate(A->comm,A->m,A->n,A->m,A->n,F);CHKERRQ(ierr);
2453b3e256bSKris Buschelman   ierr                       = MatSetType(*F,A->type_name);CHKERRQ(ierr);
2463b3e256bSKris Buschelman   ierr                       = MatSeqAIJSetPreallocation(*F,0,PETSC_NULL);CHKERRQ(ierr);
24705db81ecSKris Buschelman   (*F)->ops->solve           = MatSolve_Matlab_QR;
24805db81ecSKris Buschelman   (*F)->ops->lufactornumeric = MatLUFactorNumeric_Matlab_QR;
2493b3e256bSKris Buschelman   (*F)->factor               = FACTOR_LU;
2503b3e256bSKris Buschelman   (*F)->assembled            = PETSC_TRUE;  /* required by -ksp_view */
2513b3e256bSKris Buschelman 
2523b3e256bSKris Buschelman   PetscFunctionReturn(0);
2533b3e256bSKris Buschelman }
2543b3e256bSKris Buschelman 
2553b3e256bSKris Buschelman /* --------------------------------------------------------------------------------*/
2563b3e256bSKris Buschelman #undef __FUNCT__
25705db81ecSKris Buschelman #define __FUNCT__ "MatILUDTFactor_Matlab"
258*7529efd4SKris Buschelman PetscErrorCode MatILUDTFactor_Matlab(Mat A,IS isrow,IS iscol,MatFactorInfo *info,Mat *F)
2593b3e256bSKris Buschelman {
260dfbe8321SBarry Smith   PetscErrorCode ierr;
261de4209c5SBarry Smith   size_t     len;
2623b3e256bSKris Buschelman   char       *_A,*name;
2633b3e256bSKris Buschelman 
2643b3e256bSKris Buschelman   PetscFunctionBegin;
2653b3e256bSKris Buschelman   if (info->dt == PETSC_DEFAULT)      info->dt      = .005;
2663b3e256bSKris Buschelman   if (info->dtcol == PETSC_DEFAULT)   info->dtcol   = .01;
2673b3e256bSKris Buschelman   if (A->N != A->M) SETERRQ(PETSC_ERR_ARG_SIZ,"matrix must be square");
2683b3e256bSKris Buschelman   ierr                       = MatCreate(A->comm,A->m,A->n,A->m,A->n,F);CHKERRQ(ierr);
2693b3e256bSKris Buschelman   ierr                       = MatSetType(*F,A->type_name);CHKERRQ(ierr);
2703b3e256bSKris Buschelman   ierr                       = MatSeqAIJSetPreallocation(*F,0,PETSC_NULL);CHKERRQ(ierr);
271f365a357SKris Buschelman   (*F)->ops->solve           = MatSolve_Matlab;
2723b3e256bSKris Buschelman   (*F)->factor               = FACTOR_LU;
2733b3e256bSKris Buschelman   ierr = PetscMatlabEnginePut(PETSC_MATLAB_ENGINE_(A->comm),(PetscObject)A);CHKERRQ(ierr);
2743b3e256bSKris Buschelman   _A   = A->name;
2753b3e256bSKris Buschelman   ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(A->comm),"info_%s = struct('droptol',%g,'thresh',%g);",_A,info->dt,info->dtcol);CHKERRQ(ierr);
2763b3e256bSKris Buschelman   ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(A->comm),"[l_%s,u_%s,p_%s] = luinc(%s',info_%s);",_A,_A,_A,_A,_A);CHKERRQ(ierr);
2773b3e256bSKris Buschelman   ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(A->comm),"%s = 0;",_A);CHKERRQ(ierr);
2783b3e256bSKris Buschelman 
2793b3e256bSKris Buschelman   ierr = PetscStrlen(_A,&len);CHKERRQ(ierr);
2803b3e256bSKris Buschelman   ierr = PetscMalloc((len+2)*sizeof(char),&name);CHKERRQ(ierr);
2813b3e256bSKris Buschelman   sprintf(name,"_%s",_A);
2823b3e256bSKris Buschelman   ierr = PetscObjectSetName((PetscObject)*F,name);CHKERRQ(ierr);
2833b3e256bSKris Buschelman   ierr = PetscFree(name);CHKERRQ(ierr);
2843b3e256bSKris Buschelman   PetscFunctionReturn(0);
2853b3e256bSKris Buschelman }
2863b3e256bSKris Buschelman 
28705db81ecSKris Buschelman #undef __FUNCT__
28805db81ecSKris Buschelman #define __FUNCT__ "MatFactorInfo_Matlab"
289dfbe8321SBarry Smith PetscErrorCode MatFactorInfo_Matlab(Mat A,PetscViewer viewer)
2903b3e256bSKris Buschelman {
291dfbe8321SBarry Smith   PetscErrorCode ierr;
2923b3e256bSKris Buschelman 
2933b3e256bSKris Buschelman   PetscFunctionBegin;
2943b3e256bSKris Buschelman   ierr = PetscViewerASCIIPrintf(viewer,"Matlab run parameters:  -- not written yet!\n");CHKERRQ(ierr);
2953b3e256bSKris Buschelman   PetscFunctionReturn(0);
2963b3e256bSKris Buschelman }
2973b3e256bSKris Buschelman 
2983b3e256bSKris Buschelman #undef __FUNCT__
29905db81ecSKris Buschelman #define __FUNCT__ "MatView_Matlab"
300dfbe8321SBarry Smith PetscErrorCode MatView_Matlab(Mat A,PetscViewer viewer) {
301dfbe8321SBarry Smith   PetscErrorCode    ierr;
30232077d6dSBarry Smith   PetscTruth        iascii;
30305db81ecSKris Buschelman   PetscViewerFormat format;
30405db81ecSKris Buschelman   Mat_Matlab        *lu=(Mat_Matlab*)(A->spptr);
30505db81ecSKris Buschelman 
30605db81ecSKris Buschelman   PetscFunctionBegin;
30705db81ecSKris Buschelman   ierr = (*lu->MatView)(A,viewer);CHKERRQ(ierr);
30832077d6dSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);CHKERRQ(ierr);
30932077d6dSBarry Smith   if (iascii) {
31005db81ecSKris Buschelman     ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
31105db81ecSKris Buschelman     if (format == PETSC_VIEWER_ASCII_FACTOR_INFO) {
31205db81ecSKris Buschelman       ierr = MatFactorInfo_Matlab(A,viewer);
31305db81ecSKris Buschelman     }
31405db81ecSKris Buschelman   }
31505db81ecSKris Buschelman   PetscFunctionReturn(0);
31605db81ecSKris Buschelman }
317f365a357SKris Buschelman 
318f365a357SKris Buschelman #undef __FUNCT__
319f365a357SKris Buschelman #define __FUNCT__ "MatDuplicate_Matlab"
320dfbe8321SBarry Smith PetscErrorCode MatDuplicate_Matlab(Mat A, MatDuplicateOption op, Mat *M) {
321dfbe8321SBarry Smith   PetscErrorCode ierr;
322f365a357SKris Buschelman   Mat_Matlab *lu=(Mat_Matlab*)A->spptr;
323f365a357SKris Buschelman 
324f365a357SKris Buschelman   PetscFunctionBegin;
325f365a357SKris Buschelman   ierr = (*lu->MatDuplicate)(A,op,M);CHKERRQ(ierr);
326f365a357SKris Buschelman   ierr = PetscMemcpy((*M)->spptr,lu,sizeof(Mat_Matlab));CHKERRQ(ierr);
327f365a357SKris Buschelman   PetscFunctionReturn(0);
328f365a357SKris Buschelman }
329f365a357SKris Buschelman 
330f365a357SKris Buschelman EXTERN_C_BEGIN
33105db81ecSKris Buschelman #undef __FUNCT__
33205db81ecSKris Buschelman #define __FUNCT__ "MatConvert_SeqAIJ_Matlab"
333ceb03754SKris Buschelman PetscErrorCode MatConvert_SeqAIJ_Matlab(Mat A,const MatType type,MatReuse reuse,Mat *newmat)
334521d7252SBarry Smith {
33505db81ecSKris Buschelman   /* This routine is only called to convert to MATMATLAB */
33605db81ecSKris Buschelman   /* from MATSEQAIJ, so we will ignore 'MatType type'. */
337dfbe8321SBarry Smith   PetscErrorCode ierr;
33805db81ecSKris Buschelman   Mat            B=*newmat;
33905db81ecSKris Buschelman   Mat_Matlab     *lu;
3403b3e256bSKris Buschelman   PetscTruth     qr;
34105db81ecSKris Buschelman 
34205db81ecSKris Buschelman   PetscFunctionBegin;
343ceb03754SKris Buschelman   if (reuse == MAT_INITIAL_MATRIX) {
34405db81ecSKris Buschelman     ierr = MatDuplicate(A,MAT_COPY_VALUES,&B);CHKERRQ(ierr);
34505db81ecSKris Buschelman   }
34605db81ecSKris Buschelman 
34705db81ecSKris Buschelman   ierr = PetscNew(Mat_Matlab,&lu);CHKERRQ(ierr);
34805db81ecSKris Buschelman   lu->MatDuplicate         = A->ops->duplicate;
34905db81ecSKris Buschelman   lu->MatView              = A->ops->view;
35005db81ecSKris Buschelman   lu->MatLUFactorSymbolic  = A->ops->lufactorsymbolic;
35105db81ecSKris Buschelman   lu->MatILUDTFactor       = A->ops->iludtfactor;
35205db81ecSKris Buschelman   lu->MatDestroy           = A->ops->destroy;
35305db81ecSKris Buschelman 
35405db81ecSKris Buschelman   B->spptr                 = (void*)lu;
35505db81ecSKris Buschelman   B->ops->duplicate        = MatDuplicate_Matlab;
35605db81ecSKris Buschelman   B->ops->view             = MatView_Matlab;
35705db81ecSKris Buschelman   B->ops->lufactorsymbolic = MatLUFactorSymbolic_Matlab;
35805db81ecSKris Buschelman   B->ops->iludtfactor      = MatILUDTFactor_Matlab;
35905db81ecSKris Buschelman   B->ops->destroy          = MatDestroy_Matlab;
36005db81ecSKris Buschelman 
36105db81ecSKris Buschelman   ierr = PetscOptionsHasName(A->prefix,"-mat_matlab_qr",&qr);CHKERRQ(ierr);
36205db81ecSKris Buschelman   if (qr) {
36305db81ecSKris Buschelman     B->ops->lufactorsymbolic = MatLUFactorSymbolic_Matlab_QR;
36452e6d16bSBarry Smith     PetscLogInfo(0,"MatConvert_SeqAIJ_Matlab:Using Matlab QR with iterative refinement for LU factorization and solves");
36505db81ecSKris Buschelman   } else {
36652e6d16bSBarry Smith     PetscLogInfo(0,"MatConvert_SeqAIJ_Matlab:Using Matlab for LU factorizations and solves.");
36705db81ecSKris Buschelman   }
36852e6d16bSBarry Smith   PetscLogInfo(0,"MatConvert_SeqAIJ_Matlab:Using Matlab for ILUDT factorizations and solves.");
36905db81ecSKris Buschelman 
37005db81ecSKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqaij_matlab_C",
37105db81ecSKris Buschelman                                            "MatConvert_SeqAIJ_Matlab",MatConvert_SeqAIJ_Matlab);CHKERRQ(ierr);
37205db81ecSKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_matlab_seqaij_C",
37305db81ecSKris Buschelman                                            "MatConvert_Matlab_SeqAIJ",MatConvert_Matlab_SeqAIJ);CHKERRQ(ierr);
374a1d52234SKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"PetscMatlabEnginePut_C",
375a1d52234SKris Buschelman                                            "MatMatlabEnginePut_Matlab",MatMatlabEnginePut_Matlab);CHKERRQ(ierr);
376a1d52234SKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"PetscMatlabEngineGet_C",
377a1d52234SKris Buschelman                                            "MatMatlabEngineGet_Matlab",MatMatlabEngineGet_Matlab);CHKERRQ(ierr);
37805db81ecSKris Buschelman   ierr = PetscObjectChangeTypeName((PetscObject)B,MATMATLAB);CHKERRQ(ierr);
37905db81ecSKris Buschelman   *newmat = B;
38005db81ecSKris Buschelman   PetscFunctionReturn(0);
38105db81ecSKris Buschelman }
38205db81ecSKris Buschelman EXTERN_C_END
38305db81ecSKris Buschelman 
38405db81ecSKris Buschelman /*MC
38505db81ecSKris Buschelman   MATMATLAB - MATMATLAB = "matlab" - A matrix type providing direct solvers (LU and QR) and drop tolerance
38605db81ecSKris Buschelman   based ILU factorization (ILUDT) for sequential matrices via the external package Matlab.
38705db81ecSKris Buschelman 
38805db81ecSKris Buschelman   If Matlab is instaled (see the manual for
38905db81ecSKris Buschelman   instructions on how to declare the existence of external packages),
39005db81ecSKris Buschelman   a matrix type can be constructed which invokes Matlab solvers.
39105db81ecSKris Buschelman   After calling MatCreate(...,A), simply call MatSetType(A,MATMATLAB).
39205db81ecSKris Buschelman   This matrix type is only supported for double precision real.
39305db81ecSKris Buschelman 
39405db81ecSKris Buschelman   This matrix inherits from MATSEQAIJ.  As a result, MatSeqAIJSetPreallocation is
39505db81ecSKris Buschelman   supported for this matrix type.  One can also call MatConvert for an inplace conversion to or from
39605db81ecSKris Buschelman   the MATSEQAIJ type without data copy.
39705db81ecSKris Buschelman 
39805db81ecSKris Buschelman   Options Database Keys:
39905db81ecSKris Buschelman + -mat_type matlab - sets the matrix type to "matlab" during a call to MatSetFromOptions()
40005db81ecSKris Buschelman - -mat_matlab_qr   - sets the direct solver to be QR instead of LU
40105db81ecSKris Buschelman 
40205db81ecSKris Buschelman   Level: beginner
40305db81ecSKris Buschelman 
40405db81ecSKris Buschelman .seealso: PCLU
40505db81ecSKris Buschelman M*/
40605db81ecSKris Buschelman 
40705db81ecSKris Buschelman EXTERN_C_BEGIN
40805db81ecSKris Buschelman #undef __FUNCT__
40905db81ecSKris Buschelman #define __FUNCT__ "MatCreate_Matlab"
410dfbe8321SBarry Smith PetscErrorCode MatCreate_Matlab(Mat A)
411dfbe8321SBarry Smith {
412dfbe8321SBarry Smith   PetscErrorCode ierr;
4133b3e256bSKris Buschelman 
4143b3e256bSKris Buschelman   PetscFunctionBegin;
41505db81ecSKris Buschelman   ierr = PetscObjectChangeTypeName((PetscObject)A,MATMATLAB);CHKERRQ(ierr);
41605db81ecSKris Buschelman   ierr = MatSetType(A,MATSEQAIJ);CHKERRQ(ierr);
417ceb03754SKris Buschelman   ierr = MatConvert_SeqAIJ_Matlab(A,MATMATLAB,MAT_REUSE_MATRIX,&A);CHKERRQ(ierr);
4183b3e256bSKris Buschelman   PetscFunctionReturn(0);
4193b3e256bSKris Buschelman }
42005db81ecSKris Buschelman EXTERN_C_END
421