xref: /petsc/src/mat/impls/aij/seq/matlab/aijmatlab.c (revision 1f03425e4fb99472879b5b210f4eafb1a993b05c)
1be1d678aSKris Buschelman #define PETSCMAT_DLL
2be1d678aSKris Buschelman 
33b3e256bSKris Buschelman /*
43b3e256bSKris Buschelman         Provides an interface for the Matlab engine sparse solver
53b3e256bSKris Buschelman 
63b3e256bSKris Buschelman */
73b3e256bSKris Buschelman #include "src/mat/impls/aij/seq/aij.h"
83b3e256bSKris Buschelman 
93b3e256bSKris Buschelman #include "engine.h"   /* Matlab include file */
103b3e256bSKris Buschelman #include "mex.h"      /* Matlab include file */
113b3e256bSKris Buschelman 
1205db81ecSKris Buschelman typedef struct {
136849ba73SBarry Smith   PetscErrorCode (*MatDuplicate)(Mat,MatDuplicateOption,Mat*);
146849ba73SBarry Smith   PetscErrorCode (*MatView)(Mat,PetscViewer);
156849ba73SBarry Smith   PetscErrorCode (*MatLUFactorSymbolic)(Mat,IS,IS,MatFactorInfo*,Mat*);
167529efd4SKris Buschelman   PetscErrorCode (*MatILUDTFactor)(Mat,IS,IS,MatFactorInfo*,Mat*);
176849ba73SBarry Smith   PetscErrorCode (*MatDestroy)(Mat);
1805db81ecSKris Buschelman } Mat_Matlab;
1905db81ecSKris Buschelman 
20a1d52234SKris Buschelman 
21a1d52234SKris Buschelman EXTERN_C_BEGIN
22a1d52234SKris Buschelman #undef __FUNCT__
23a1d52234SKris Buschelman #define __FUNCT__ "MatMatlabEnginePut_Matlab"
24be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatMatlabEnginePut_Matlab(PetscObject obj,void *mengine)
25a1d52234SKris Buschelman {
26dfbe8321SBarry Smith   PetscErrorCode ierr;
27a1d52234SKris Buschelman   Mat            B = (Mat)obj;
28a1d52234SKris Buschelman   mxArray        *mat;
29a1d52234SKris Buschelman   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*)B->data;
30a1d52234SKris Buschelman 
31a1d52234SKris Buschelman   PetscFunctionBegin;
322a4c71feSBarry Smith   mat  = mxCreateSparse(B->cmap.n,B->rmap.n,aij->nz,mxREAL);
33a1d52234SKris Buschelman   ierr = PetscMemcpy(mxGetPr(mat),aij->a,aij->nz*sizeof(PetscScalar));CHKERRQ(ierr);
34a1d52234SKris Buschelman   /* Matlab stores by column, not row so we pass in the transpose of the matrix */
35a1d52234SKris Buschelman   ierr = PetscMemcpy(mxGetIr(mat),aij->j,aij->nz*sizeof(int));CHKERRQ(ierr);
362a4c71feSBarry Smith   ierr = PetscMemcpy(mxGetJc(mat),aij->i,(B->rmap.n+1)*sizeof(int));CHKERRQ(ierr);
37a1d52234SKris Buschelman 
38a1d52234SKris Buschelman   /* Matlab indices start at 0 for sparse (what a surprise) */
39a1d52234SKris Buschelman 
40a1d52234SKris Buschelman   ierr = PetscObjectName(obj);CHKERRQ(ierr);
41a1d52234SKris Buschelman   engPutVariable((Engine *)mengine,obj->name,mat);
42a1d52234SKris Buschelman   PetscFunctionReturn(0);
43a1d52234SKris Buschelman }
44a1d52234SKris Buschelman EXTERN_C_END
45a1d52234SKris Buschelman 
46a1d52234SKris Buschelman EXTERN_C_BEGIN
47a1d52234SKris Buschelman #undef __FUNCT__
48a1d52234SKris Buschelman #define __FUNCT__ "MatMatlabEngineGet_Matlab"
49be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatMatlabEngineGet_Matlab(PetscObject obj,void *mengine)
50a1d52234SKris Buschelman {
51dfbe8321SBarry Smith   PetscErrorCode ierr;
52dfbe8321SBarry Smith   int            ii;
53a1d52234SKris Buschelman   Mat            mat = (Mat)obj;
54a1d52234SKris Buschelman   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*)mat->data;
55a1d52234SKris Buschelman   mxArray        *mmat;
56a1d52234SKris Buschelman 
57a1d52234SKris Buschelman   PetscFunctionBegin;
58*1f03425eSSatish Balay   ierr = MatSeqXAIJFreeAIJ(mat,&aij->a,&aij->j,&aij->i);CHKERRQ(ierr);
59a1d52234SKris Buschelman 
60a1d52234SKris Buschelman   mmat = engGetVariable((Engine *)mengine,obj->name);
61a1d52234SKris Buschelman 
622a4c71feSBarry Smith   aij->nz           = (mxGetJc(mmat))[mat->rmap.n];
632a4c71feSBarry Smith   ierr  = PetscMalloc3(aij->nz,PetscScalar,&aij->a,aij->nz,PetscInt,&aij->j,mat->rmap.n+1,PetscInt,&aij->i);CHKERRQ(ierr);
64a1d52234SKris Buschelman   aij->singlemalloc = PETSC_TRUE;
65a1d52234SKris Buschelman 
66a1d52234SKris Buschelman   ierr = PetscMemcpy(aij->a,mxGetPr(mmat),aij->nz*sizeof(PetscScalar));CHKERRQ(ierr);
67a1d52234SKris Buschelman   /* Matlab stores by column, not row so we pass in the transpose of the matrix */
68a1d52234SKris Buschelman   ierr = PetscMemcpy(aij->j,mxGetIr(mmat),aij->nz*sizeof(int));CHKERRQ(ierr);
692a4c71feSBarry Smith   ierr = PetscMemcpy(aij->i,mxGetJc(mmat),(mat->rmap.n+1)*sizeof(int));CHKERRQ(ierr);
70a1d52234SKris Buschelman 
712a4c71feSBarry Smith   for (ii=0; ii<mat->rmap.n; ii++) {
72a1d52234SKris Buschelman     aij->ilen[ii] = aij->imax[ii] = aij->i[ii+1] - aij->i[ii];
73a1d52234SKris Buschelman   }
74a1d52234SKris Buschelman 
75a1d52234SKris Buschelman   ierr = MatAssemblyBegin(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
76a1d52234SKris Buschelman   ierr = MatAssemblyEnd(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
77a1d52234SKris Buschelman 
78a1d52234SKris Buschelman   PetscFunctionReturn(0);
79a1d52234SKris Buschelman }
80a1d52234SKris Buschelman EXTERN_C_END
81a1d52234SKris Buschelman 
8205db81ecSKris Buschelman EXTERN_C_BEGIN
833b3e256bSKris Buschelman #undef __FUNCT__
8405db81ecSKris Buschelman #define __FUNCT__ "MatConvert_Matlab_SeqAIJ"
85b2d3331aSBarry Smith PetscErrorCode PETSCMAT_DLLEXPORT MatConvert_Matlab_SeqAIJ(Mat A,MatType type,MatReuse reuse,Mat *newmat)
86521d7252SBarry Smith {
87dfbe8321SBarry Smith   PetscErrorCode ierr;
8805db81ecSKris Buschelman   Mat            B=*newmat;
8905db81ecSKris Buschelman   Mat_Matlab    *lu=(Mat_Matlab*)A->spptr;
9005db81ecSKris Buschelman 
9105db81ecSKris Buschelman   PetscFunctionBegin;
92ceb03754SKris Buschelman   if (reuse == MAT_INITIAL_MATRIX) {
9305db81ecSKris Buschelman     ierr = MatDuplicate(A,MAT_COPY_VALUES,&B);CHKERRQ(ierr);
9405db81ecSKris Buschelman   }
95901853e0SKris Buschelman   B->ops->duplicate        = lu->MatDuplicate;
96901853e0SKris Buschelman   B->ops->view             = lu->MatView;
97901853e0SKris Buschelman   B->ops->lufactorsymbolic = lu->MatLUFactorSymbolic;
98901853e0SKris Buschelman   B->ops->iludtfactor      = lu->MatILUDTFactor;
99901853e0SKris Buschelman   B->ops->destroy          = lu->MatDestroy;
10005db81ecSKris Buschelman 
10105db81ecSKris Buschelman   ierr = PetscFree(lu);CHKERRQ(ierr);
102901853e0SKris Buschelman 
103901853e0SKris Buschelman   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_matlab_C","",PETSC_NULL);CHKERRQ(ierr);
104901853e0SKris Buschelman   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_matlab_seqaij_C","",PETSC_NULL);CHKERRQ(ierr);
105901853e0SKris Buschelman   ierr = PetscObjectComposeFunction((PetscObject)B,"PetscMatlabEnginePut_C","",PETSC_NULL);CHKERRQ(ierr);
106901853e0SKris Buschelman   ierr = PetscObjectComposeFunction((PetscObject)B,"PetscMatlabEngineGet_C","",PETSC_NULL);CHKERRQ(ierr);
107901853e0SKris Buschelman 
10805db81ecSKris Buschelman   ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr);
10905db81ecSKris Buschelman   *newmat = B;
11005db81ecSKris Buschelman   PetscFunctionReturn(0);
11105db81ecSKris Buschelman }
11205db81ecSKris Buschelman EXTERN_C_END
11305db81ecSKris Buschelman 
11405db81ecSKris Buschelman #undef __FUNCT__
11505db81ecSKris Buschelman #define __FUNCT__ "MatDestroy_Matlab"
116dfbe8321SBarry Smith PetscErrorCode MatDestroy_Matlab(Mat A)
117dfbe8321SBarry Smith {
118dfbe8321SBarry Smith   PetscErrorCode ierr;
11905db81ecSKris Buschelman 
12005db81ecSKris Buschelman   PetscFunctionBegin;
121b2d3331aSBarry Smith   ierr = MatConvert_Matlab_SeqAIJ(A,MATSEQAIJ,MAT_REUSE_MATRIX,&A);CHKERRQ(ierr);
12205db81ecSKris Buschelman   ierr = (*A->ops->destroy)(A);CHKERRQ(ierr);
12305db81ecSKris Buschelman   PetscFunctionReturn(0);
12405db81ecSKris Buschelman }
12505db81ecSKris Buschelman 
12605db81ecSKris Buschelman #undef __FUNCT__
12705db81ecSKris Buschelman #define __FUNCT__ "MatSolve_Matlab"
128dfbe8321SBarry Smith PetscErrorCode MatSolve_Matlab(Mat A,Vec b,Vec x)
1293b3e256bSKris Buschelman {
130dfbe8321SBarry Smith   PetscErrorCode ierr;
131e060cb09SBarry Smith   const char     *_A,*_b,*_x;
1323b3e256bSKris Buschelman 
1333b3e256bSKris Buschelman   PetscFunctionBegin;
1343b3e256bSKris Buschelman   /* make sure objects have names; use default if not */
1353b3e256bSKris Buschelman   ierr = PetscObjectName((PetscObject)b);CHKERRQ(ierr);
1363b3e256bSKris Buschelman   ierr = PetscObjectName((PetscObject)x);CHKERRQ(ierr);
1373b3e256bSKris Buschelman 
1383b3e256bSKris Buschelman   ierr = PetscObjectGetName((PetscObject)A,&_A);CHKERRQ(ierr);
1393b3e256bSKris Buschelman   ierr = PetscObjectGetName((PetscObject)b,&_b);CHKERRQ(ierr);
1403b3e256bSKris Buschelman   ierr = PetscObjectGetName((PetscObject)x,&_x);CHKERRQ(ierr);
1413b3e256bSKris Buschelman   ierr = PetscMatlabEnginePut(PETSC_MATLAB_ENGINE_(A->comm),(PetscObject)b);CHKERRQ(ierr);
1423b3e256bSKris Buschelman   ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(A->comm),"%s = u%s\\(l%s\\(p%s*%s));",_x,_A,_A,_A,_b);CHKERRQ(ierr);
1433b3e256bSKris Buschelman   ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(A->comm),"%s = 0;",_b);CHKERRQ(ierr);
1443b3e256bSKris Buschelman   /* ierr = PetscMatlabEnginePrintOutput(PETSC_MATLAB_ENGINE_(A->comm),stdout);CHKERRQ(ierr);  */
1453b3e256bSKris Buschelman   ierr = PetscMatlabEngineGet(PETSC_MATLAB_ENGINE_(A->comm),(PetscObject)x);CHKERRQ(ierr);
1463b3e256bSKris Buschelman   PetscFunctionReturn(0);
1473b3e256bSKris Buschelman }
1483b3e256bSKris Buschelman 
1493b3e256bSKris Buschelman #undef __FUNCT__
15005db81ecSKris Buschelman #define __FUNCT__ "MatLUFactorNumeric_Matlab"
151af281ebdSHong Zhang PetscErrorCode MatLUFactorNumeric_Matlab(Mat A,MatFactorInfo *info,Mat *F)
1523b3e256bSKris Buschelman {
153dfbe8321SBarry Smith   PetscErrorCode ierr;
154de4209c5SBarry Smith   size_t         len;
1553b3e256bSKris Buschelman   char           *_A,*name;
1563b3e256bSKris Buschelman 
1573b3e256bSKris Buschelman   PetscFunctionBegin;
1583b3e256bSKris Buschelman   ierr = PetscMatlabEnginePut(PETSC_MATLAB_ENGINE_(A->comm),(PetscObject)A);CHKERRQ(ierr);
1593b3e256bSKris Buschelman   _A   = A->name;
1601d18e487SKris Buschelman   ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(A->comm),"[l_%s,u_%s,p_%s] = lu(%s',%g);",_A,_A,_A,_A,info->dtcol);CHKERRQ(ierr);
1613b3e256bSKris Buschelman   ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(A->comm),"%s = 0;",_A);CHKERRQ(ierr);
1623b3e256bSKris Buschelman   ierr = PetscStrlen(_A,&len);CHKERRQ(ierr);
1633b3e256bSKris Buschelman   ierr = PetscMalloc((len+2)*sizeof(char),&name);CHKERRQ(ierr);
1643b3e256bSKris Buschelman   sprintf(name,"_%s",_A);
1653b3e256bSKris Buschelman   ierr = PetscObjectSetName((PetscObject)*F,name);CHKERRQ(ierr);
1663b3e256bSKris Buschelman   ierr = PetscFree(name);CHKERRQ(ierr);
1673b3e256bSKris Buschelman   PetscFunctionReturn(0);
1683b3e256bSKris Buschelman }
1693b3e256bSKris Buschelman 
1703b3e256bSKris Buschelman #undef __FUNCT__
17105db81ecSKris Buschelman #define __FUNCT__ "MatLUFactorSymbolic_Matlab"
172dfbe8321SBarry Smith PetscErrorCode MatLUFactorSymbolic_Matlab(Mat A,IS r,IS c,MatFactorInfo *info,Mat *F)
1733b3e256bSKris Buschelman {
174dfbe8321SBarry Smith   PetscErrorCode ierr;
1753b3e256bSKris Buschelman 
1763b3e256bSKris Buschelman   PetscFunctionBegin;
1772a4c71feSBarry Smith   if (A->cmap.N != A->rmap.N) SETERRQ(PETSC_ERR_ARG_SIZ,"matrix must be square");
178f69a0ea3SMatthew Knepley   ierr                       = MatCreate(A->comm,F);CHKERRQ(ierr);
1792a4c71feSBarry Smith   ierr                       = MatSetSizes(*F,A->rmap.n,A->cmap.n,A->rmap.n,A->cmap.n);CHKERRQ(ierr);
1803b3e256bSKris Buschelman   ierr                       = MatSetType(*F,A->type_name);CHKERRQ(ierr);
1813b3e256bSKris Buschelman   ierr                       = MatSeqAIJSetPreallocation(*F,0,PETSC_NULL);CHKERRQ(ierr);
18205db81ecSKris Buschelman   (*F)->ops->solve           = MatSolve_Matlab;
18305db81ecSKris Buschelman   (*F)->ops->lufactornumeric = MatLUFactorNumeric_Matlab;
1843b3e256bSKris Buschelman   (*F)->factor               = FACTOR_LU;
1853b3e256bSKris Buschelman   PetscFunctionReturn(0);
1863b3e256bSKris Buschelman }
1873b3e256bSKris Buschelman 
1883b3e256bSKris Buschelman /* ---------------------------------------------------------------------------------*/
1893b3e256bSKris Buschelman #undef __FUNCT__
19005db81ecSKris Buschelman #define __FUNCT__ "MatSolve_Matlab_QR"
191dfbe8321SBarry Smith PetscErrorCode MatSolve_Matlab_QR(Mat A,Vec b,Vec x)
1923b3e256bSKris Buschelman {
193dfbe8321SBarry Smith   PetscErrorCode ierr;
194e060cb09SBarry Smith   const char     *_A,*_b,*_x;
1953b3e256bSKris Buschelman 
1963b3e256bSKris Buschelman   PetscFunctionBegin;
1973b3e256bSKris Buschelman   /* make sure objects have names; use default if not */
1983b3e256bSKris Buschelman   ierr = PetscObjectName((PetscObject)b);CHKERRQ(ierr);
1993b3e256bSKris Buschelman   ierr = PetscObjectName((PetscObject)x);CHKERRQ(ierr);
2003b3e256bSKris Buschelman 
2013b3e256bSKris Buschelman   ierr = PetscObjectGetName((PetscObject)A,&_A);CHKERRQ(ierr);
2023b3e256bSKris Buschelman   ierr = PetscObjectGetName((PetscObject)b,&_b);CHKERRQ(ierr);
2033b3e256bSKris Buschelman   ierr = PetscObjectGetName((PetscObject)x,&_x);CHKERRQ(ierr);
2043b3e256bSKris Buschelman   ierr = PetscMatlabEnginePut(PETSC_MATLAB_ENGINE_(A->comm),(PetscObject)b);CHKERRQ(ierr);
2053b3e256bSKris Buschelman   ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(A->comm),"%s = r%s\\(r%s'\\(%s*%s));",_x,_A,_A,_A+1,_b);CHKERRQ(ierr);
2063b3e256bSKris Buschelman   ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(A->comm),"%s = 0;",_b);CHKERRQ(ierr);
2073b3e256bSKris Buschelman   /* ierr = PetscMatlabEnginePrintOutput(PETSC_MATLAB_ENGINE_(A->comm),stdout);CHKERRQ(ierr);  */
2083b3e256bSKris Buschelman   ierr = PetscMatlabEngineGet(PETSC_MATLAB_ENGINE_(A->comm),(PetscObject)x);CHKERRQ(ierr);
2093b3e256bSKris Buschelman   PetscFunctionReturn(0);
2103b3e256bSKris Buschelman }
2113b3e256bSKris Buschelman 
2123b3e256bSKris Buschelman #undef __FUNCT__
21305db81ecSKris Buschelman #define __FUNCT__ "MatLUFactorNumeric_Matlab_QR"
214af281ebdSHong Zhang PetscErrorCode MatLUFactorNumeric_Matlab_QR(Mat A,MatFactorInfo *info,Mat *F)
2153b3e256bSKris Buschelman {
216dfbe8321SBarry Smith   PetscErrorCode ierr;
217de4209c5SBarry Smith   size_t         len;
2183b3e256bSKris Buschelman   char           *_A,*name;
2193b3e256bSKris Buschelman 
2203b3e256bSKris Buschelman   PetscFunctionBegin;
2213b3e256bSKris Buschelman   ierr = PetscMatlabEnginePut(PETSC_MATLAB_ENGINE_(A->comm),(PetscObject)A);CHKERRQ(ierr);
2223b3e256bSKris Buschelman   _A   = A->name;
2233b3e256bSKris Buschelman   ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(A->comm),"r_%s = qr(%s');",_A,_A);CHKERRQ(ierr);
2243b3e256bSKris Buschelman   ierr = PetscStrlen(_A,&len);CHKERRQ(ierr);
2253b3e256bSKris Buschelman   ierr = PetscMalloc((len+2)*sizeof(char),&name);CHKERRQ(ierr);
2263b3e256bSKris Buschelman   sprintf(name,"_%s",_A);
2273b3e256bSKris Buschelman   ierr = PetscObjectSetName((PetscObject)*F,name);CHKERRQ(ierr);
2283b3e256bSKris Buschelman   ierr = PetscFree(name);CHKERRQ(ierr);
2293b3e256bSKris Buschelman   PetscFunctionReturn(0);
2303b3e256bSKris Buschelman }
2313b3e256bSKris Buschelman 
2323b3e256bSKris Buschelman #undef __FUNCT__
23305db81ecSKris Buschelman #define __FUNCT__ "MatLUFactorSymbolic_Matlab_QR"
234dfbe8321SBarry Smith PetscErrorCode MatLUFactorSymbolic_Matlab_QR(Mat A,IS r,IS c,MatFactorInfo *info,Mat *F)
2353b3e256bSKris Buschelman {
236dfbe8321SBarry Smith   PetscErrorCode ierr;
2373b3e256bSKris Buschelman 
2383b3e256bSKris Buschelman   PetscFunctionBegin;
2392a4c71feSBarry Smith   if (A->cmap.N != A->rmap.N) SETERRQ(PETSC_ERR_ARG_SIZ,"matrix must be square");
240f69a0ea3SMatthew Knepley   ierr                       = MatCreate(A->comm,F);CHKERRQ(ierr);
2412a4c71feSBarry Smith   ierr                       = MatSetSizes(*F,A->rmap.n,A->cmap.n,A->rmap.n,A->cmap.n);CHKERRQ(ierr);
2423b3e256bSKris Buschelman   ierr                       = MatSetType(*F,A->type_name);CHKERRQ(ierr);
2433b3e256bSKris Buschelman   ierr                       = MatSeqAIJSetPreallocation(*F,0,PETSC_NULL);CHKERRQ(ierr);
24405db81ecSKris Buschelman   (*F)->ops->solve           = MatSolve_Matlab_QR;
24505db81ecSKris Buschelman   (*F)->ops->lufactornumeric = MatLUFactorNumeric_Matlab_QR;
2463b3e256bSKris Buschelman   (*F)->factor               = FACTOR_LU;
2473b3e256bSKris Buschelman   (*F)->assembled            = PETSC_TRUE;  /* required by -ksp_view */
2483b3e256bSKris Buschelman 
2493b3e256bSKris Buschelman   PetscFunctionReturn(0);
2503b3e256bSKris Buschelman }
2513b3e256bSKris Buschelman 
2523b3e256bSKris Buschelman /* --------------------------------------------------------------------------------*/
2533b3e256bSKris Buschelman #undef __FUNCT__
25405db81ecSKris Buschelman #define __FUNCT__ "MatILUDTFactor_Matlab"
2557529efd4SKris Buschelman PetscErrorCode MatILUDTFactor_Matlab(Mat A,IS isrow,IS iscol,MatFactorInfo *info,Mat *F)
2563b3e256bSKris Buschelman {
257dfbe8321SBarry Smith   PetscErrorCode ierr;
258de4209c5SBarry Smith   size_t         len;
2593b3e256bSKris Buschelman   char           *_A,*name;
2603b3e256bSKris Buschelman 
2613b3e256bSKris Buschelman   PetscFunctionBegin;
2623b3e256bSKris Buschelman   if (info->dt == PETSC_DEFAULT)      info->dt      = .005;
2633b3e256bSKris Buschelman   if (info->dtcol == PETSC_DEFAULT)   info->dtcol   = .01;
2642a4c71feSBarry Smith   if (A->cmap.N != A->rmap.N) SETERRQ(PETSC_ERR_ARG_SIZ,"matrix must be square");
265f69a0ea3SMatthew Knepley   ierr                       = MatCreate(A->comm,F);CHKERRQ(ierr);
2662a4c71feSBarry Smith   ierr                       = MatSetSizes(*F,A->rmap.n,A->cmap.n,A->rmap.n,A->cmap.n);CHKERRQ(ierr);
2673b3e256bSKris Buschelman   ierr                       = MatSetType(*F,A->type_name);CHKERRQ(ierr);
2683b3e256bSKris Buschelman   ierr                       = MatSeqAIJSetPreallocation(*F,0,PETSC_NULL);CHKERRQ(ierr);
269f365a357SKris Buschelman   (*F)->ops->solve           = MatSolve_Matlab;
2703b3e256bSKris Buschelman   (*F)->factor               = FACTOR_LU;
2713b3e256bSKris Buschelman   ierr = PetscMatlabEnginePut(PETSC_MATLAB_ENGINE_(A->comm),(PetscObject)A);CHKERRQ(ierr);
2723b3e256bSKris Buschelman   _A   = A->name;
2733b3e256bSKris Buschelman   ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(A->comm),"info_%s = struct('droptol',%g,'thresh',%g);",_A,info->dt,info->dtcol);CHKERRQ(ierr);
2743b3e256bSKris 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);
2753b3e256bSKris Buschelman   ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(A->comm),"%s = 0;",_A);CHKERRQ(ierr);
2763b3e256bSKris Buschelman 
2773b3e256bSKris Buschelman   ierr = PetscStrlen(_A,&len);CHKERRQ(ierr);
2783b3e256bSKris Buschelman   ierr = PetscMalloc((len+2)*sizeof(char),&name);CHKERRQ(ierr);
2793b3e256bSKris Buschelman   sprintf(name,"_%s",_A);
2803b3e256bSKris Buschelman   ierr = PetscObjectSetName((PetscObject)*F,name);CHKERRQ(ierr);
2813b3e256bSKris Buschelman   ierr = PetscFree(name);CHKERRQ(ierr);
2823b3e256bSKris Buschelman   PetscFunctionReturn(0);
2833b3e256bSKris Buschelman }
2843b3e256bSKris Buschelman 
28505db81ecSKris Buschelman #undef __FUNCT__
28605db81ecSKris Buschelman #define __FUNCT__ "MatFactorInfo_Matlab"
287dfbe8321SBarry Smith PetscErrorCode MatFactorInfo_Matlab(Mat A,PetscViewer viewer)
2883b3e256bSKris Buschelman {
289dfbe8321SBarry Smith   PetscErrorCode ierr;
2903b3e256bSKris Buschelman 
2913b3e256bSKris Buschelman   PetscFunctionBegin;
2923b3e256bSKris Buschelman   ierr = PetscViewerASCIIPrintf(viewer,"Matlab run parameters:  -- not written yet!\n");CHKERRQ(ierr);
2933b3e256bSKris Buschelman   PetscFunctionReturn(0);
2943b3e256bSKris Buschelman }
2953b3e256bSKris Buschelman 
2963b3e256bSKris Buschelman #undef __FUNCT__
29705db81ecSKris Buschelman #define __FUNCT__ "MatView_Matlab"
298b2d3331aSBarry Smith PetscErrorCode MatView_Matlab(Mat A,PetscViewer viewer)
299b2d3331aSBarry Smith {
300dfbe8321SBarry Smith   PetscErrorCode    ierr;
30132077d6dSBarry Smith   PetscTruth        iascii;
30205db81ecSKris Buschelman   PetscViewerFormat format;
30305db81ecSKris Buschelman   Mat_Matlab        *lu=(Mat_Matlab*)(A->spptr);
30405db81ecSKris Buschelman 
30505db81ecSKris Buschelman   PetscFunctionBegin;
30605db81ecSKris Buschelman   ierr = (*lu->MatView)(A,viewer);CHKERRQ(ierr);
30732077d6dSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);CHKERRQ(ierr);
30832077d6dSBarry Smith   if (iascii) {
30905db81ecSKris Buschelman     ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
31005db81ecSKris Buschelman     if (format == PETSC_VIEWER_ASCII_FACTOR_INFO) {
31105db81ecSKris Buschelman       ierr = MatFactorInfo_Matlab(A,viewer);
31205db81ecSKris Buschelman     }
31305db81ecSKris Buschelman   }
31405db81ecSKris Buschelman   PetscFunctionReturn(0);
31505db81ecSKris Buschelman }
316f365a357SKris Buschelman 
317f365a357SKris Buschelman #undef __FUNCT__
318f365a357SKris Buschelman #define __FUNCT__ "MatDuplicate_Matlab"
319b2d3331aSBarry Smith PetscErrorCode MatDuplicate_Matlab(Mat A, MatDuplicateOption op, Mat *M)
320b2d3331aSBarry Smith {
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"
333b2d3331aSBarry Smith PetscErrorCode PETSCMAT_DLLEXPORT MatConvert_SeqAIJ_Matlab(Mat A,MatType type,MatReuse reuse,Mat *newmat)
334521d7252SBarry Smith {
335dfbe8321SBarry Smith   PetscErrorCode ierr;
33605db81ecSKris Buschelman   Mat            B=*newmat;
33705db81ecSKris Buschelman   Mat_Matlab     *lu;
3383b3e256bSKris Buschelman   PetscTruth     qr;
33905db81ecSKris Buschelman 
34005db81ecSKris Buschelman   PetscFunctionBegin;
341ceb03754SKris Buschelman   if (reuse == MAT_INITIAL_MATRIX) {
34205db81ecSKris Buschelman     ierr = MatDuplicate(A,MAT_COPY_VALUES,&B);CHKERRQ(ierr);
34305db81ecSKris Buschelman   }
34405db81ecSKris Buschelman 
34505db81ecSKris Buschelman   ierr = PetscNew(Mat_Matlab,&lu);CHKERRQ(ierr);
34605db81ecSKris Buschelman   lu->MatDuplicate         = A->ops->duplicate;
34705db81ecSKris Buschelman   lu->MatView              = A->ops->view;
34805db81ecSKris Buschelman   lu->MatLUFactorSymbolic  = A->ops->lufactorsymbolic;
34905db81ecSKris Buschelman   lu->MatILUDTFactor       = A->ops->iludtfactor;
35005db81ecSKris Buschelman   lu->MatDestroy           = A->ops->destroy;
35105db81ecSKris Buschelman 
35205db81ecSKris Buschelman   B->spptr                 = (void*)lu;
35305db81ecSKris Buschelman   B->ops->duplicate        = MatDuplicate_Matlab;
35405db81ecSKris Buschelman   B->ops->view             = MatView_Matlab;
35505db81ecSKris Buschelman   B->ops->lufactorsymbolic = MatLUFactorSymbolic_Matlab;
35605db81ecSKris Buschelman   B->ops->iludtfactor      = MatILUDTFactor_Matlab;
35705db81ecSKris Buschelman   B->ops->destroy          = MatDestroy_Matlab;
35805db81ecSKris Buschelman 
35905db81ecSKris Buschelman   ierr = PetscOptionsHasName(A->prefix,"-mat_matlab_qr",&qr);CHKERRQ(ierr);
36005db81ecSKris Buschelman   if (qr) {
36105db81ecSKris Buschelman     B->ops->lufactorsymbolic = MatLUFactorSymbolic_Matlab_QR;
362ae15b995SBarry Smith     ierr = PetscInfo(0,"Using Matlab QR with iterative refinement for LU factorization and solves\n");CHKERRQ(ierr);
36305db81ecSKris Buschelman   } else {
364ae15b995SBarry Smith     ierr = PetscInfo(0,"Using Matlab for LU factorizations and solves.\n");CHKERRQ(ierr);
36505db81ecSKris Buschelman   }
366ae15b995SBarry Smith   ierr = PetscInfo(0,"Using Matlab for ILUDT factorizations and solves.\n");CHKERRQ(ierr);
36705db81ecSKris Buschelman 
36805db81ecSKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqaij_matlab_C",
36905db81ecSKris Buschelman                                            "MatConvert_SeqAIJ_Matlab",MatConvert_SeqAIJ_Matlab);CHKERRQ(ierr);
37005db81ecSKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_matlab_seqaij_C",
37105db81ecSKris Buschelman                                            "MatConvert_Matlab_SeqAIJ",MatConvert_Matlab_SeqAIJ);CHKERRQ(ierr);
372a1d52234SKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"PetscMatlabEnginePut_C",
373a1d52234SKris Buschelman                                            "MatMatlabEnginePut_Matlab",MatMatlabEnginePut_Matlab);CHKERRQ(ierr);
374a1d52234SKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"PetscMatlabEngineGet_C",
375a1d52234SKris Buschelman                                            "MatMatlabEngineGet_Matlab",MatMatlabEngineGet_Matlab);CHKERRQ(ierr);
37605db81ecSKris Buschelman   ierr = PetscObjectChangeTypeName((PetscObject)B,MATMATLAB);CHKERRQ(ierr);
37705db81ecSKris Buschelman   *newmat = B;
37805db81ecSKris Buschelman   PetscFunctionReturn(0);
37905db81ecSKris Buschelman }
38005db81ecSKris Buschelman EXTERN_C_END
38105db81ecSKris Buschelman 
38205db81ecSKris Buschelman /*MC
38305db81ecSKris Buschelman   MATMATLAB - MATMATLAB = "matlab" - A matrix type providing direct solvers (LU and QR) and drop tolerance
38405db81ecSKris Buschelman   based ILU factorization (ILUDT) for sequential matrices via the external package Matlab.
38505db81ecSKris Buschelman 
38605db81ecSKris Buschelman   If Matlab is instaled (see the manual for
38705db81ecSKris Buschelman   instructions on how to declare the existence of external packages),
38805db81ecSKris Buschelman   a matrix type can be constructed which invokes Matlab solvers.
38905db81ecSKris Buschelman   After calling MatCreate(...,A), simply call MatSetType(A,MATMATLAB).
39005db81ecSKris Buschelman   This matrix type is only supported for double precision real.
39105db81ecSKris Buschelman 
39205db81ecSKris Buschelman   This matrix inherits from MATSEQAIJ.  As a result, MatSeqAIJSetPreallocation is
39305db81ecSKris Buschelman   supported for this matrix type.  One can also call MatConvert for an inplace conversion to or from
39405db81ecSKris Buschelman   the MATSEQAIJ type without data copy.
39505db81ecSKris Buschelman 
39605db81ecSKris Buschelman   Options Database Keys:
39705db81ecSKris Buschelman + -mat_type matlab - sets the matrix type to "matlab" during a call to MatSetFromOptions()
39805db81ecSKris Buschelman - -mat_matlab_qr   - sets the direct solver to be QR instead of LU
39905db81ecSKris Buschelman 
40005db81ecSKris Buschelman   Level: beginner
40105db81ecSKris Buschelman 
40205db81ecSKris Buschelman .seealso: PCLU
40305db81ecSKris Buschelman M*/
40405db81ecSKris Buschelman 
40505db81ecSKris Buschelman EXTERN_C_BEGIN
40605db81ecSKris Buschelman #undef __FUNCT__
40705db81ecSKris Buschelman #define __FUNCT__ "MatCreate_Matlab"
408be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatCreate_Matlab(Mat A)
409dfbe8321SBarry Smith {
410dfbe8321SBarry Smith   PetscErrorCode ierr;
4113b3e256bSKris Buschelman 
4123b3e256bSKris Buschelman   PetscFunctionBegin;
41305db81ecSKris Buschelman   ierr = MatSetType(A,MATSEQAIJ);CHKERRQ(ierr);
414ceb03754SKris Buschelman   ierr = MatConvert_SeqAIJ_Matlab(A,MATMATLAB,MAT_REUSE_MATRIX,&A);CHKERRQ(ierr);
4153b3e256bSKris Buschelman   PetscFunctionReturn(0);
4163b3e256bSKris Buschelman }
41705db81ecSKris Buschelman EXTERN_C_END
418