xref: /petsc/src/mat/impls/aij/seq/matlab/aijmatlab.c (revision a96a251defc07734f733d1abf27b5765e87fdc8b)
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;
32a1d52234SKris Buschelman   mat  = mxCreateSparse(B->n,B->m,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);
36a1d52234SKris Buschelman   ierr = PetscMemcpy(mxGetJc(mat),aij->i,(B->m+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*a96a251dSBarry Smith   if (!aij->singlemalloc) {
59a1d52234SKris Buschelman     ierr = PetscFree(aij->a);CHKERRQ(ierr);
60*a96a251dSBarry Smith     ierr = PetscFree(aij->j);CHKERRQ(ierr);
61*a96a251dSBarry Smith     ierr = PetscFree(aij->i);CHKERRQ(ierr);
62*a96a251dSBarry Smith   } else {
63*a96a251dSBarry Smith     ierr = PetscFree3(aij->a,aij->j,aij->i);CHKERRQ(ierr);
64*a96a251dSBarry Smith   }
65a1d52234SKris Buschelman 
66a1d52234SKris Buschelman   mmat = engGetVariable((Engine *)mengine,obj->name);
67a1d52234SKris Buschelman 
68a1d52234SKris Buschelman   aij->nz           = (mxGetJc(mmat))[mat->m];
69*a96a251dSBarry Smith   ierr  = PetscMalloc3(aij->nz,PetscScalar,&aij->a,aij->nz,PetscInt,&aij->j,mat->m+1,PetscInt,&aij->i);CHKERRQ(ierr);
70a1d52234SKris Buschelman   aij->singlemalloc = PETSC_TRUE;
71a1d52234SKris Buschelman   aij->freedata     = PETSC_TRUE;
72a1d52234SKris Buschelman 
73a1d52234SKris Buschelman   ierr = PetscMemcpy(aij->a,mxGetPr(mmat),aij->nz*sizeof(PetscScalar));CHKERRQ(ierr);
74a1d52234SKris Buschelman   /* Matlab stores by column, not row so we pass in the transpose of the matrix */
75a1d52234SKris Buschelman   ierr = PetscMemcpy(aij->j,mxGetIr(mmat),aij->nz*sizeof(int));CHKERRQ(ierr);
76a1d52234SKris Buschelman   ierr = PetscMemcpy(aij->i,mxGetJc(mmat),(mat->m+1)*sizeof(int));CHKERRQ(ierr);
77a1d52234SKris Buschelman 
78a1d52234SKris Buschelman   for (ii=0; ii<mat->m; ii++) {
79a1d52234SKris Buschelman     aij->ilen[ii] = aij->imax[ii] = aij->i[ii+1] - aij->i[ii];
80a1d52234SKris Buschelman   }
81a1d52234SKris Buschelman 
82a1d52234SKris Buschelman   ierr = MatAssemblyBegin(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
83a1d52234SKris Buschelman   ierr = MatAssemblyEnd(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
84a1d52234SKris Buschelman 
85a1d52234SKris Buschelman   PetscFunctionReturn(0);
86a1d52234SKris Buschelman }
87a1d52234SKris Buschelman EXTERN_C_END
88a1d52234SKris Buschelman 
8905db81ecSKris Buschelman EXTERN_C_BEGIN
903b3e256bSKris Buschelman #undef __FUNCT__
9105db81ecSKris Buschelman #define __FUNCT__ "MatConvert_Matlab_SeqAIJ"
92be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatConvert_Matlab_SeqAIJ(Mat A,const MatType type,MatReuse reuse,Mat *newmat)
93521d7252SBarry Smith {
94dfbe8321SBarry Smith   PetscErrorCode ierr;
9505db81ecSKris Buschelman   Mat            B=*newmat;
9605db81ecSKris Buschelman   Mat_Matlab    *lu=(Mat_Matlab*)A->spptr;
9705db81ecSKris Buschelman 
9805db81ecSKris Buschelman   PetscFunctionBegin;
99ceb03754SKris Buschelman   if (reuse == MAT_INITIAL_MATRIX) {
10005db81ecSKris Buschelman     ierr = MatDuplicate(A,MAT_COPY_VALUES,&B);CHKERRQ(ierr);
10105db81ecSKris Buschelman   }
102901853e0SKris Buschelman   B->ops->duplicate        = lu->MatDuplicate;
103901853e0SKris Buschelman   B->ops->view             = lu->MatView;
104901853e0SKris Buschelman   B->ops->lufactorsymbolic = lu->MatLUFactorSymbolic;
105901853e0SKris Buschelman   B->ops->iludtfactor      = lu->MatILUDTFactor;
106901853e0SKris Buschelman   B->ops->destroy          = lu->MatDestroy;
10705db81ecSKris Buschelman 
10805db81ecSKris Buschelman   ierr = PetscFree(lu);CHKERRQ(ierr);
109901853e0SKris Buschelman 
110901853e0SKris Buschelman   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_matlab_C","",PETSC_NULL);CHKERRQ(ierr);
111901853e0SKris Buschelman   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_matlab_seqaij_C","",PETSC_NULL);CHKERRQ(ierr);
112901853e0SKris Buschelman   ierr = PetscObjectComposeFunction((PetscObject)B,"PetscMatlabEnginePut_C","",PETSC_NULL);CHKERRQ(ierr);
113901853e0SKris Buschelman   ierr = PetscObjectComposeFunction((PetscObject)B,"PetscMatlabEngineGet_C","",PETSC_NULL);CHKERRQ(ierr);
114901853e0SKris Buschelman 
11505db81ecSKris Buschelman   ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr);
11605db81ecSKris Buschelman   *newmat = B;
11705db81ecSKris Buschelman   PetscFunctionReturn(0);
11805db81ecSKris Buschelman }
11905db81ecSKris Buschelman EXTERN_C_END
12005db81ecSKris Buschelman 
12105db81ecSKris Buschelman #undef __FUNCT__
12205db81ecSKris Buschelman #define __FUNCT__ "MatDestroy_Matlab"
123dfbe8321SBarry Smith PetscErrorCode MatDestroy_Matlab(Mat A)
124dfbe8321SBarry Smith {
125dfbe8321SBarry Smith   PetscErrorCode ierr;
12605db81ecSKris Buschelman 
12705db81ecSKris Buschelman   PetscFunctionBegin;
12805db81ecSKris Buschelman   ierr = MatConvert_Matlab_SeqAIJ(A,MATSEQAIJ,&A);CHKERRQ(ierr);
12905db81ecSKris Buschelman   ierr = (*A->ops->destroy)(A);CHKERRQ(ierr);
13005db81ecSKris Buschelman   PetscFunctionReturn(0);
13105db81ecSKris Buschelman }
13205db81ecSKris Buschelman 
13305db81ecSKris Buschelman #undef __FUNCT__
13405db81ecSKris Buschelman #define __FUNCT__ "MatSolve_Matlab"
135dfbe8321SBarry Smith PetscErrorCode MatSolve_Matlab(Mat A,Vec b,Vec x)
1363b3e256bSKris Buschelman {
137dfbe8321SBarry Smith   PetscErrorCode ierr;
1383b3e256bSKris Buschelman   char            *_A,*_b,*_x;
1393b3e256bSKris Buschelman 
1403b3e256bSKris Buschelman   PetscFunctionBegin;
1413b3e256bSKris Buschelman   /* make sure objects have names; use default if not */
1423b3e256bSKris Buschelman   ierr = PetscObjectName((PetscObject)b);CHKERRQ(ierr);
1433b3e256bSKris Buschelman   ierr = PetscObjectName((PetscObject)x);CHKERRQ(ierr);
1443b3e256bSKris Buschelman 
1453b3e256bSKris Buschelman   ierr = PetscObjectGetName((PetscObject)A,&_A);CHKERRQ(ierr);
1463b3e256bSKris Buschelman   ierr = PetscObjectGetName((PetscObject)b,&_b);CHKERRQ(ierr);
1473b3e256bSKris Buschelman   ierr = PetscObjectGetName((PetscObject)x,&_x);CHKERRQ(ierr);
1483b3e256bSKris Buschelman   ierr = PetscMatlabEnginePut(PETSC_MATLAB_ENGINE_(A->comm),(PetscObject)b);CHKERRQ(ierr);
1493b3e256bSKris Buschelman   ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(A->comm),"%s = u%s\\(l%s\\(p%s*%s));",_x,_A,_A,_A,_b);CHKERRQ(ierr);
1503b3e256bSKris Buschelman   ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(A->comm),"%s = 0;",_b);CHKERRQ(ierr);
1513b3e256bSKris Buschelman   /* ierr = PetscMatlabEnginePrintOutput(PETSC_MATLAB_ENGINE_(A->comm),stdout);CHKERRQ(ierr);  */
1523b3e256bSKris Buschelman   ierr = PetscMatlabEngineGet(PETSC_MATLAB_ENGINE_(A->comm),(PetscObject)x);CHKERRQ(ierr);
1533b3e256bSKris Buschelman   PetscFunctionReturn(0);
1543b3e256bSKris Buschelman }
1553b3e256bSKris Buschelman 
1563b3e256bSKris Buschelman #undef __FUNCT__
15705db81ecSKris Buschelman #define __FUNCT__ "MatLUFactorNumeric_Matlab"
158af281ebdSHong Zhang PetscErrorCode MatLUFactorNumeric_Matlab(Mat A,MatFactorInfo *info,Mat *F)
1593b3e256bSKris Buschelman {
1603b3e256bSKris Buschelman   Mat_SeqAIJ      *f = (Mat_SeqAIJ*)(*F)->data;
161dfbe8321SBarry Smith   PetscErrorCode ierr;
162de4209c5SBarry Smith   size_t          len;
1633b3e256bSKris Buschelman   char            *_A,*name;
1643b3e256bSKris Buschelman 
1653b3e256bSKris Buschelman   PetscFunctionBegin;
1663b3e256bSKris Buschelman   ierr = PetscMatlabEnginePut(PETSC_MATLAB_ENGINE_(A->comm),(PetscObject)A);CHKERRQ(ierr);
1673b3e256bSKris Buschelman   _A   = A->name;
1681d18e487SKris 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);
1693b3e256bSKris Buschelman   ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(A->comm),"%s = 0;",_A);CHKERRQ(ierr);
1703b3e256bSKris Buschelman   ierr = PetscStrlen(_A,&len);CHKERRQ(ierr);
1713b3e256bSKris Buschelman   ierr = PetscMalloc((len+2)*sizeof(char),&name);CHKERRQ(ierr);
1723b3e256bSKris Buschelman   sprintf(name,"_%s",_A);
1733b3e256bSKris Buschelman   ierr = PetscObjectSetName((PetscObject)*F,name);CHKERRQ(ierr);
1743b3e256bSKris Buschelman   ierr = PetscFree(name);CHKERRQ(ierr);
1753b3e256bSKris Buschelman   PetscFunctionReturn(0);
1763b3e256bSKris Buschelman }
1773b3e256bSKris Buschelman 
1783b3e256bSKris Buschelman #undef __FUNCT__
17905db81ecSKris Buschelman #define __FUNCT__ "MatLUFactorSymbolic_Matlab"
180dfbe8321SBarry Smith PetscErrorCode MatLUFactorSymbolic_Matlab(Mat A,IS r,IS c,MatFactorInfo *info,Mat *F)
1813b3e256bSKris Buschelman {
182dfbe8321SBarry Smith   PetscErrorCode ierr;
1833b3e256bSKris Buschelman   Mat_SeqAIJ *f;
1843b3e256bSKris Buschelman 
1853b3e256bSKris Buschelman   PetscFunctionBegin;
1863b3e256bSKris Buschelman   if (A->N != A->M) SETERRQ(PETSC_ERR_ARG_SIZ,"matrix must be square");
1873b3e256bSKris Buschelman   ierr                       = MatCreate(A->comm,A->m,A->n,A->m,A->n,F);CHKERRQ(ierr);
1883b3e256bSKris Buschelman   ierr                       = MatSetType(*F,A->type_name);CHKERRQ(ierr);
1893b3e256bSKris Buschelman   ierr                       = MatSeqAIJSetPreallocation(*F,0,PETSC_NULL);CHKERRQ(ierr);
19005db81ecSKris Buschelman   (*F)->ops->solve           = MatSolve_Matlab;
19105db81ecSKris Buschelman   (*F)->ops->lufactornumeric = MatLUFactorNumeric_Matlab;
1923b3e256bSKris Buschelman   (*F)->factor               = FACTOR_LU;
1933b3e256bSKris Buschelman   f                          = (Mat_SeqAIJ*)(*F)->data;
1943b3e256bSKris Buschelman   f->lu_dtcol = info->dtcol;
1953b3e256bSKris Buschelman   PetscFunctionReturn(0);
1963b3e256bSKris Buschelman }
1973b3e256bSKris Buschelman 
1983b3e256bSKris Buschelman /* ---------------------------------------------------------------------------------*/
1993b3e256bSKris Buschelman #undef __FUNCT__
20005db81ecSKris Buschelman #define __FUNCT__ "MatSolve_Matlab_QR"
201dfbe8321SBarry Smith PetscErrorCode MatSolve_Matlab_QR(Mat A,Vec b,Vec x)
2023b3e256bSKris Buschelman {
203dfbe8321SBarry Smith   PetscErrorCode ierr;
2043b3e256bSKris Buschelman   char            *_A,*_b,*_x;
2053b3e256bSKris Buschelman 
2063b3e256bSKris Buschelman   PetscFunctionBegin;
2073b3e256bSKris Buschelman   /* make sure objects have names; use default if not */
2083b3e256bSKris Buschelman   ierr = PetscObjectName((PetscObject)b);CHKERRQ(ierr);
2093b3e256bSKris Buschelman   ierr = PetscObjectName((PetscObject)x);CHKERRQ(ierr);
2103b3e256bSKris Buschelman 
2113b3e256bSKris Buschelman   ierr = PetscObjectGetName((PetscObject)A,&_A);CHKERRQ(ierr);
2123b3e256bSKris Buschelman   ierr = PetscObjectGetName((PetscObject)b,&_b);CHKERRQ(ierr);
2133b3e256bSKris Buschelman   ierr = PetscObjectGetName((PetscObject)x,&_x);CHKERRQ(ierr);
2143b3e256bSKris Buschelman   ierr = PetscMatlabEnginePut(PETSC_MATLAB_ENGINE_(A->comm),(PetscObject)b);CHKERRQ(ierr);
2153b3e256bSKris Buschelman   ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(A->comm),"%s = r%s\\(r%s'\\(%s*%s));",_x,_A,_A,_A+1,_b);CHKERRQ(ierr);
2163b3e256bSKris Buschelman   ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(A->comm),"%s = 0;",_b);CHKERRQ(ierr);
2173b3e256bSKris Buschelman   /* ierr = PetscMatlabEnginePrintOutput(PETSC_MATLAB_ENGINE_(A->comm),stdout);CHKERRQ(ierr);  */
2183b3e256bSKris Buschelman   ierr = PetscMatlabEngineGet(PETSC_MATLAB_ENGINE_(A->comm),(PetscObject)x);CHKERRQ(ierr);
2193b3e256bSKris Buschelman   PetscFunctionReturn(0);
2203b3e256bSKris Buschelman }
2213b3e256bSKris Buschelman 
2223b3e256bSKris Buschelman #undef __FUNCT__
22305db81ecSKris Buschelman #define __FUNCT__ "MatLUFactorNumeric_Matlab_QR"
224af281ebdSHong Zhang PetscErrorCode MatLUFactorNumeric_Matlab_QR(Mat A,MatFactorInfo *info,Mat *F)
2253b3e256bSKris Buschelman {
226dfbe8321SBarry Smith   PetscErrorCode ierr;
227de4209c5SBarry Smith   size_t          len;
2283b3e256bSKris Buschelman   char            *_A,*name;
2293b3e256bSKris Buschelman 
2303b3e256bSKris Buschelman   PetscFunctionBegin;
2313b3e256bSKris Buschelman   ierr = PetscMatlabEnginePut(PETSC_MATLAB_ENGINE_(A->comm),(PetscObject)A);CHKERRQ(ierr);
2323b3e256bSKris Buschelman   _A   = A->name;
2333b3e256bSKris Buschelman   ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(A->comm),"r_%s = qr(%s');",_A,_A);CHKERRQ(ierr);
2343b3e256bSKris Buschelman   ierr = PetscStrlen(_A,&len);CHKERRQ(ierr);
2353b3e256bSKris Buschelman   ierr = PetscMalloc((len+2)*sizeof(char),&name);CHKERRQ(ierr);
2363b3e256bSKris Buschelman   sprintf(name,"_%s",_A);
2373b3e256bSKris Buschelman   ierr = PetscObjectSetName((PetscObject)*F,name);CHKERRQ(ierr);
2383b3e256bSKris Buschelman   ierr = PetscFree(name);CHKERRQ(ierr);
2393b3e256bSKris Buschelman   PetscFunctionReturn(0);
2403b3e256bSKris Buschelman }
2413b3e256bSKris Buschelman 
2423b3e256bSKris Buschelman #undef __FUNCT__
24305db81ecSKris Buschelman #define __FUNCT__ "MatLUFactorSymbolic_Matlab_QR"
244dfbe8321SBarry Smith PetscErrorCode MatLUFactorSymbolic_Matlab_QR(Mat A,IS r,IS c,MatFactorInfo *info,Mat *F)
2453b3e256bSKris Buschelman {
246dfbe8321SBarry Smith   PetscErrorCode ierr;
2473b3e256bSKris Buschelman 
2483b3e256bSKris Buschelman   PetscFunctionBegin;
2493b3e256bSKris Buschelman   if (A->N != A->M) SETERRQ(PETSC_ERR_ARG_SIZ,"matrix must be square");
2503b3e256bSKris Buschelman   ierr                       = MatCreate(A->comm,A->m,A->n,A->m,A->n,F);CHKERRQ(ierr);
2513b3e256bSKris Buschelman   ierr                       = MatSetType(*F,A->type_name);CHKERRQ(ierr);
2523b3e256bSKris Buschelman   ierr                       = MatSeqAIJSetPreallocation(*F,0,PETSC_NULL);CHKERRQ(ierr);
25305db81ecSKris Buschelman   (*F)->ops->solve           = MatSolve_Matlab_QR;
25405db81ecSKris Buschelman   (*F)->ops->lufactornumeric = MatLUFactorNumeric_Matlab_QR;
2553b3e256bSKris Buschelman   (*F)->factor               = FACTOR_LU;
2563b3e256bSKris Buschelman   (*F)->assembled            = PETSC_TRUE;  /* required by -ksp_view */
2573b3e256bSKris Buschelman 
2583b3e256bSKris Buschelman   PetscFunctionReturn(0);
2593b3e256bSKris Buschelman }
2603b3e256bSKris Buschelman 
2613b3e256bSKris Buschelman /* --------------------------------------------------------------------------------*/
2623b3e256bSKris Buschelman #undef __FUNCT__
26305db81ecSKris Buschelman #define __FUNCT__ "MatILUDTFactor_Matlab"
2647529efd4SKris Buschelman PetscErrorCode MatILUDTFactor_Matlab(Mat A,IS isrow,IS iscol,MatFactorInfo *info,Mat *F)
2653b3e256bSKris Buschelman {
266dfbe8321SBarry Smith   PetscErrorCode ierr;
267de4209c5SBarry Smith   size_t     len;
2683b3e256bSKris Buschelman   char       *_A,*name;
2693b3e256bSKris Buschelman 
2703b3e256bSKris Buschelman   PetscFunctionBegin;
2713b3e256bSKris Buschelman   if (info->dt == PETSC_DEFAULT)      info->dt      = .005;
2723b3e256bSKris Buschelman   if (info->dtcol == PETSC_DEFAULT)   info->dtcol   = .01;
2733b3e256bSKris Buschelman   if (A->N != A->M) SETERRQ(PETSC_ERR_ARG_SIZ,"matrix must be square");
2743b3e256bSKris Buschelman   ierr                       = MatCreate(A->comm,A->m,A->n,A->m,A->n,F);CHKERRQ(ierr);
2753b3e256bSKris Buschelman   ierr                       = MatSetType(*F,A->type_name);CHKERRQ(ierr);
2763b3e256bSKris Buschelman   ierr                       = MatSeqAIJSetPreallocation(*F,0,PETSC_NULL);CHKERRQ(ierr);
277f365a357SKris Buschelman   (*F)->ops->solve           = MatSolve_Matlab;
2783b3e256bSKris Buschelman   (*F)->factor               = FACTOR_LU;
2793b3e256bSKris Buschelman   ierr = PetscMatlabEnginePut(PETSC_MATLAB_ENGINE_(A->comm),(PetscObject)A);CHKERRQ(ierr);
2803b3e256bSKris Buschelman   _A   = A->name;
2813b3e256bSKris Buschelman   ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(A->comm),"info_%s = struct('droptol',%g,'thresh',%g);",_A,info->dt,info->dtcol);CHKERRQ(ierr);
2823b3e256bSKris 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);
2833b3e256bSKris Buschelman   ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(A->comm),"%s = 0;",_A);CHKERRQ(ierr);
2843b3e256bSKris Buschelman 
2853b3e256bSKris Buschelman   ierr = PetscStrlen(_A,&len);CHKERRQ(ierr);
2863b3e256bSKris Buschelman   ierr = PetscMalloc((len+2)*sizeof(char),&name);CHKERRQ(ierr);
2873b3e256bSKris Buschelman   sprintf(name,"_%s",_A);
2883b3e256bSKris Buschelman   ierr = PetscObjectSetName((PetscObject)*F,name);CHKERRQ(ierr);
2893b3e256bSKris Buschelman   ierr = PetscFree(name);CHKERRQ(ierr);
2903b3e256bSKris Buschelman   PetscFunctionReturn(0);
2913b3e256bSKris Buschelman }
2923b3e256bSKris Buschelman 
29305db81ecSKris Buschelman #undef __FUNCT__
29405db81ecSKris Buschelman #define __FUNCT__ "MatFactorInfo_Matlab"
295dfbe8321SBarry Smith PetscErrorCode MatFactorInfo_Matlab(Mat A,PetscViewer viewer)
2963b3e256bSKris Buschelman {
297dfbe8321SBarry Smith   PetscErrorCode ierr;
2983b3e256bSKris Buschelman 
2993b3e256bSKris Buschelman   PetscFunctionBegin;
3003b3e256bSKris Buschelman   ierr = PetscViewerASCIIPrintf(viewer,"Matlab run parameters:  -- not written yet!\n");CHKERRQ(ierr);
3013b3e256bSKris Buschelman   PetscFunctionReturn(0);
3023b3e256bSKris Buschelman }
3033b3e256bSKris Buschelman 
3043b3e256bSKris Buschelman #undef __FUNCT__
30505db81ecSKris Buschelman #define __FUNCT__ "MatView_Matlab"
306dfbe8321SBarry Smith PetscErrorCode MatView_Matlab(Mat A,PetscViewer viewer) {
307dfbe8321SBarry Smith   PetscErrorCode    ierr;
30832077d6dSBarry Smith   PetscTruth        iascii;
30905db81ecSKris Buschelman   PetscViewerFormat format;
31005db81ecSKris Buschelman   Mat_Matlab        *lu=(Mat_Matlab*)(A->spptr);
31105db81ecSKris Buschelman 
31205db81ecSKris Buschelman   PetscFunctionBegin;
31305db81ecSKris Buschelman   ierr = (*lu->MatView)(A,viewer);CHKERRQ(ierr);
31432077d6dSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);CHKERRQ(ierr);
31532077d6dSBarry Smith   if (iascii) {
31605db81ecSKris Buschelman     ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
31705db81ecSKris Buschelman     if (format == PETSC_VIEWER_ASCII_FACTOR_INFO) {
31805db81ecSKris Buschelman       ierr = MatFactorInfo_Matlab(A,viewer);
31905db81ecSKris Buschelman     }
32005db81ecSKris Buschelman   }
32105db81ecSKris Buschelman   PetscFunctionReturn(0);
32205db81ecSKris Buschelman }
323f365a357SKris Buschelman 
324f365a357SKris Buschelman #undef __FUNCT__
325f365a357SKris Buschelman #define __FUNCT__ "MatDuplicate_Matlab"
326dfbe8321SBarry Smith PetscErrorCode MatDuplicate_Matlab(Mat A, MatDuplicateOption op, Mat *M) {
327dfbe8321SBarry Smith   PetscErrorCode ierr;
328f365a357SKris Buschelman   Mat_Matlab *lu=(Mat_Matlab*)A->spptr;
329f365a357SKris Buschelman 
330f365a357SKris Buschelman   PetscFunctionBegin;
331f365a357SKris Buschelman   ierr = (*lu->MatDuplicate)(A,op,M);CHKERRQ(ierr);
332f365a357SKris Buschelman   ierr = PetscMemcpy((*M)->spptr,lu,sizeof(Mat_Matlab));CHKERRQ(ierr);
333f365a357SKris Buschelman   PetscFunctionReturn(0);
334f365a357SKris Buschelman }
335f365a357SKris Buschelman 
336f365a357SKris Buschelman EXTERN_C_BEGIN
33705db81ecSKris Buschelman #undef __FUNCT__
33805db81ecSKris Buschelman #define __FUNCT__ "MatConvert_SeqAIJ_Matlab"
339be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatConvert_SeqAIJ_Matlab(Mat A,const MatType type,MatReuse reuse,Mat *newmat)
340521d7252SBarry Smith {
34105db81ecSKris Buschelman   /* This routine is only called to convert to MATMATLAB */
34205db81ecSKris Buschelman   /* from MATSEQAIJ, so we will ignore 'MatType type'. */
343dfbe8321SBarry Smith   PetscErrorCode ierr;
34405db81ecSKris Buschelman   Mat            B=*newmat;
34505db81ecSKris Buschelman   Mat_Matlab     *lu;
3463b3e256bSKris Buschelman   PetscTruth     qr;
34705db81ecSKris Buschelman 
34805db81ecSKris Buschelman   PetscFunctionBegin;
349ceb03754SKris Buschelman   if (reuse == MAT_INITIAL_MATRIX) {
35005db81ecSKris Buschelman     ierr = MatDuplicate(A,MAT_COPY_VALUES,&B);CHKERRQ(ierr);
35105db81ecSKris Buschelman   }
35205db81ecSKris Buschelman 
35305db81ecSKris Buschelman   ierr = PetscNew(Mat_Matlab,&lu);CHKERRQ(ierr);
35405db81ecSKris Buschelman   lu->MatDuplicate         = A->ops->duplicate;
35505db81ecSKris Buschelman   lu->MatView              = A->ops->view;
35605db81ecSKris Buschelman   lu->MatLUFactorSymbolic  = A->ops->lufactorsymbolic;
35705db81ecSKris Buschelman   lu->MatILUDTFactor       = A->ops->iludtfactor;
35805db81ecSKris Buschelman   lu->MatDestroy           = A->ops->destroy;
35905db81ecSKris Buschelman 
36005db81ecSKris Buschelman   B->spptr                 = (void*)lu;
36105db81ecSKris Buschelman   B->ops->duplicate        = MatDuplicate_Matlab;
36205db81ecSKris Buschelman   B->ops->view             = MatView_Matlab;
36305db81ecSKris Buschelman   B->ops->lufactorsymbolic = MatLUFactorSymbolic_Matlab;
36405db81ecSKris Buschelman   B->ops->iludtfactor      = MatILUDTFactor_Matlab;
36505db81ecSKris Buschelman   B->ops->destroy          = MatDestroy_Matlab;
36605db81ecSKris Buschelman 
36705db81ecSKris Buschelman   ierr = PetscOptionsHasName(A->prefix,"-mat_matlab_qr",&qr);CHKERRQ(ierr);
36805db81ecSKris Buschelman   if (qr) {
36905db81ecSKris Buschelman     B->ops->lufactorsymbolic = MatLUFactorSymbolic_Matlab_QR;
37063ba0a88SBarry Smith     ierr = PetscLogInfo((0,"MatConvert_SeqAIJ_Matlab:Using Matlab QR with iterative refinement for LU factorization and solves\n"));CHKERRQ(ierr);
37105db81ecSKris Buschelman   } else {
37263ba0a88SBarry Smith     ierr = PetscLogInfo((0,"MatConvert_SeqAIJ_Matlab:Using Matlab for LU factorizations and solves.\n"));CHKERRQ(ierr);
37305db81ecSKris Buschelman   }
37463ba0a88SBarry Smith   ierr = PetscLogInfo((0,"MatConvert_SeqAIJ_Matlab:Using Matlab for ILUDT factorizations and solves.\n"));CHKERRQ(ierr);
37505db81ecSKris Buschelman 
37605db81ecSKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqaij_matlab_C",
37705db81ecSKris Buschelman                                            "MatConvert_SeqAIJ_Matlab",MatConvert_SeqAIJ_Matlab);CHKERRQ(ierr);
37805db81ecSKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_matlab_seqaij_C",
37905db81ecSKris Buschelman                                            "MatConvert_Matlab_SeqAIJ",MatConvert_Matlab_SeqAIJ);CHKERRQ(ierr);
380a1d52234SKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"PetscMatlabEnginePut_C",
381a1d52234SKris Buschelman                                            "MatMatlabEnginePut_Matlab",MatMatlabEnginePut_Matlab);CHKERRQ(ierr);
382a1d52234SKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"PetscMatlabEngineGet_C",
383a1d52234SKris Buschelman                                            "MatMatlabEngineGet_Matlab",MatMatlabEngineGet_Matlab);CHKERRQ(ierr);
38405db81ecSKris Buschelman   ierr = PetscObjectChangeTypeName((PetscObject)B,MATMATLAB);CHKERRQ(ierr);
38505db81ecSKris Buschelman   *newmat = B;
38605db81ecSKris Buschelman   PetscFunctionReturn(0);
38705db81ecSKris Buschelman }
38805db81ecSKris Buschelman EXTERN_C_END
38905db81ecSKris Buschelman 
39005db81ecSKris Buschelman /*MC
39105db81ecSKris Buschelman   MATMATLAB - MATMATLAB = "matlab" - A matrix type providing direct solvers (LU and QR) and drop tolerance
39205db81ecSKris Buschelman   based ILU factorization (ILUDT) for sequential matrices via the external package Matlab.
39305db81ecSKris Buschelman 
39405db81ecSKris Buschelman   If Matlab is instaled (see the manual for
39505db81ecSKris Buschelman   instructions on how to declare the existence of external packages),
39605db81ecSKris Buschelman   a matrix type can be constructed which invokes Matlab solvers.
39705db81ecSKris Buschelman   After calling MatCreate(...,A), simply call MatSetType(A,MATMATLAB).
39805db81ecSKris Buschelman   This matrix type is only supported for double precision real.
39905db81ecSKris Buschelman 
40005db81ecSKris Buschelman   This matrix inherits from MATSEQAIJ.  As a result, MatSeqAIJSetPreallocation is
40105db81ecSKris Buschelman   supported for this matrix type.  One can also call MatConvert for an inplace conversion to or from
40205db81ecSKris Buschelman   the MATSEQAIJ type without data copy.
40305db81ecSKris Buschelman 
40405db81ecSKris Buschelman   Options Database Keys:
40505db81ecSKris Buschelman + -mat_type matlab - sets the matrix type to "matlab" during a call to MatSetFromOptions()
40605db81ecSKris Buschelman - -mat_matlab_qr   - sets the direct solver to be QR instead of LU
40705db81ecSKris Buschelman 
40805db81ecSKris Buschelman   Level: beginner
40905db81ecSKris Buschelman 
41005db81ecSKris Buschelman .seealso: PCLU
41105db81ecSKris Buschelman M*/
41205db81ecSKris Buschelman 
41305db81ecSKris Buschelman EXTERN_C_BEGIN
41405db81ecSKris Buschelman #undef __FUNCT__
41505db81ecSKris Buschelman #define __FUNCT__ "MatCreate_Matlab"
416be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatCreate_Matlab(Mat A)
417dfbe8321SBarry Smith {
418dfbe8321SBarry Smith   PetscErrorCode ierr;
4193b3e256bSKris Buschelman 
4203b3e256bSKris Buschelman   PetscFunctionBegin;
42105db81ecSKris Buschelman   ierr = PetscObjectChangeTypeName((PetscObject)A,MATMATLAB);CHKERRQ(ierr);
42205db81ecSKris Buschelman   ierr = MatSetType(A,MATSEQAIJ);CHKERRQ(ierr);
423ceb03754SKris Buschelman   ierr = MatConvert_SeqAIJ_Matlab(A,MATMATLAB,MAT_REUSE_MATRIX,&A);CHKERRQ(ierr);
4243b3e256bSKris Buschelman   PetscFunctionReturn(0);
4253b3e256bSKris Buschelman }
42605db81ecSKris Buschelman EXTERN_C_END
427