xref: /petsc/src/mat/impls/aij/seq/matlab/aijmatlab.c (revision 5c9eb25f753630cfd361293e05e7358a00a954ac)
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 
12a1d52234SKris Buschelman 
13a1d52234SKris Buschelman EXTERN_C_BEGIN
14a1d52234SKris Buschelman #undef __FUNCT__
15a1d52234SKris Buschelman #define __FUNCT__ "MatMatlabEnginePut_Matlab"
16be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatMatlabEnginePut_Matlab(PetscObject obj,void *mengine)
17a1d52234SKris Buschelman {
18dfbe8321SBarry Smith   PetscErrorCode ierr;
19a1d52234SKris Buschelman   Mat            B = (Mat)obj;
20a1d52234SKris Buschelman   mxArray        *mat;
21a1d52234SKris Buschelman   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*)B->data;
22a1d52234SKris Buschelman 
23a1d52234SKris Buschelman   PetscFunctionBegin;
242a4c71feSBarry Smith   mat  = mxCreateSparse(B->cmap.n,B->rmap.n,aij->nz,mxREAL);
25a1d52234SKris Buschelman   ierr = PetscMemcpy(mxGetPr(mat),aij->a,aij->nz*sizeof(PetscScalar));CHKERRQ(ierr);
26a1d52234SKris Buschelman   /* Matlab stores by column, not row so we pass in the transpose of the matrix */
27a1d52234SKris Buschelman   ierr = PetscMemcpy(mxGetIr(mat),aij->j,aij->nz*sizeof(int));CHKERRQ(ierr);
282a4c71feSBarry Smith   ierr = PetscMemcpy(mxGetJc(mat),aij->i,(B->rmap.n+1)*sizeof(int));CHKERRQ(ierr);
29a1d52234SKris Buschelman 
30a1d52234SKris Buschelman   /* Matlab indices start at 0 for sparse (what a surprise) */
31a1d52234SKris Buschelman 
32a1d52234SKris Buschelman   ierr = PetscObjectName(obj);CHKERRQ(ierr);
33a1d52234SKris Buschelman   engPutVariable((Engine *)mengine,obj->name,mat);
34a1d52234SKris Buschelman   PetscFunctionReturn(0);
35a1d52234SKris Buschelman }
36a1d52234SKris Buschelman EXTERN_C_END
37a1d52234SKris Buschelman 
38a1d52234SKris Buschelman EXTERN_C_BEGIN
39a1d52234SKris Buschelman #undef __FUNCT__
40a1d52234SKris Buschelman #define __FUNCT__ "MatMatlabEngineGet_Matlab"
41be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatMatlabEngineGet_Matlab(PetscObject obj,void *mengine)
42a1d52234SKris Buschelman {
43dfbe8321SBarry Smith   PetscErrorCode ierr;
44dfbe8321SBarry Smith   int            ii;
45a1d52234SKris Buschelman   Mat            mat = (Mat)obj;
46a1d52234SKris Buschelman   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*)mat->data;
47a1d52234SKris Buschelman   mxArray        *mmat;
48a1d52234SKris Buschelman 
49a1d52234SKris Buschelman   PetscFunctionBegin;
501f03425eSSatish Balay   ierr = MatSeqXAIJFreeAIJ(mat,&aij->a,&aij->j,&aij->i);CHKERRQ(ierr);
51a1d52234SKris Buschelman 
52a1d52234SKris Buschelman   mmat = engGetVariable((Engine *)mengine,obj->name);
53a1d52234SKris Buschelman 
542a4c71feSBarry Smith   aij->nz           = (mxGetJc(mmat))[mat->rmap.n];
552a4c71feSBarry Smith   ierr  = PetscMalloc3(aij->nz,PetscScalar,&aij->a,aij->nz,PetscInt,&aij->j,mat->rmap.n+1,PetscInt,&aij->i);CHKERRQ(ierr);
56a1d52234SKris Buschelman   aij->singlemalloc = PETSC_TRUE;
57a1d52234SKris Buschelman 
58a1d52234SKris Buschelman   ierr = PetscMemcpy(aij->a,mxGetPr(mmat),aij->nz*sizeof(PetscScalar));CHKERRQ(ierr);
59a1d52234SKris Buschelman   /* Matlab stores by column, not row so we pass in the transpose of the matrix */
60a1d52234SKris Buschelman   ierr = PetscMemcpy(aij->j,mxGetIr(mmat),aij->nz*sizeof(int));CHKERRQ(ierr);
612a4c71feSBarry Smith   ierr = PetscMemcpy(aij->i,mxGetJc(mmat),(mat->rmap.n+1)*sizeof(int));CHKERRQ(ierr);
62a1d52234SKris Buschelman 
632a4c71feSBarry Smith   for (ii=0; ii<mat->rmap.n; ii++) {
64a1d52234SKris Buschelman     aij->ilen[ii] = aij->imax[ii] = aij->i[ii+1] - aij->i[ii];
65a1d52234SKris Buschelman   }
66a1d52234SKris Buschelman 
67a1d52234SKris Buschelman   ierr = MatAssemblyBegin(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
68a1d52234SKris Buschelman   ierr = MatAssemblyEnd(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
69a1d52234SKris Buschelman 
70a1d52234SKris Buschelman   PetscFunctionReturn(0);
71a1d52234SKris Buschelman }
72a1d52234SKris Buschelman EXTERN_C_END
73a1d52234SKris Buschelman 
7405db81ecSKris Buschelman #undef __FUNCT__
7505db81ecSKris Buschelman #define __FUNCT__ "MatSolve_Matlab"
76dfbe8321SBarry Smith PetscErrorCode MatSolve_Matlab(Mat A,Vec b,Vec x)
773b3e256bSKris Buschelman {
78dfbe8321SBarry Smith   PetscErrorCode ierr;
79e060cb09SBarry Smith   const char     *_A,*_b,*_x;
803b3e256bSKris Buschelman 
813b3e256bSKris Buschelman   PetscFunctionBegin;
823b3e256bSKris Buschelman   /* make sure objects have names; use default if not */
833b3e256bSKris Buschelman   ierr = PetscObjectName((PetscObject)b);CHKERRQ(ierr);
843b3e256bSKris Buschelman   ierr = PetscObjectName((PetscObject)x);CHKERRQ(ierr);
853b3e256bSKris Buschelman 
863b3e256bSKris Buschelman   ierr = PetscObjectGetName((PetscObject)A,&_A);CHKERRQ(ierr);
873b3e256bSKris Buschelman   ierr = PetscObjectGetName((PetscObject)b,&_b);CHKERRQ(ierr);
883b3e256bSKris Buschelman   ierr = PetscObjectGetName((PetscObject)x,&_x);CHKERRQ(ierr);
897adad957SLisandro Dalcin   ierr = PetscMatlabEnginePut(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),(PetscObject)b);CHKERRQ(ierr);
907adad957SLisandro Dalcin   ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),"%s = u%s\\(l%s\\(p%s*%s));",_x,_A,_A,_A,_b);CHKERRQ(ierr);
917adad957SLisandro Dalcin   ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),"%s = 0;",_b);CHKERRQ(ierr);
927adad957SLisandro Dalcin   /* ierr = PetscMatlabEnginePrintOutput(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),stdout);CHKERRQ(ierr);  */
937adad957SLisandro Dalcin   ierr = PetscMatlabEngineGet(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),(PetscObject)x);CHKERRQ(ierr);
943b3e256bSKris Buschelman   PetscFunctionReturn(0);
953b3e256bSKris Buschelman }
963b3e256bSKris Buschelman 
973b3e256bSKris Buschelman #undef __FUNCT__
9805db81ecSKris Buschelman #define __FUNCT__ "MatLUFactorNumeric_Matlab"
99af281ebdSHong Zhang PetscErrorCode MatLUFactorNumeric_Matlab(Mat A,MatFactorInfo *info,Mat *F)
1003b3e256bSKris Buschelman {
101dfbe8321SBarry Smith   PetscErrorCode ierr;
102de4209c5SBarry Smith   size_t         len;
1033b3e256bSKris Buschelman   char           *_A,*name;
1043b3e256bSKris Buschelman 
1053b3e256bSKris Buschelman   PetscFunctionBegin;
1067adad957SLisandro Dalcin   ierr = PetscMatlabEnginePut(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),(PetscObject)A);CHKERRQ(ierr);
1073b3e256bSKris Buschelman   _A   = A->name;
1087adad957SLisandro Dalcin   ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),"[l_%s,u_%s,p_%s] = lu(%s',%g);",_A,_A,_A,_A,info->dtcol);CHKERRQ(ierr);
1097adad957SLisandro Dalcin   ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),"%s = 0;",_A);CHKERRQ(ierr);
1103b3e256bSKris Buschelman   ierr = PetscStrlen(_A,&len);CHKERRQ(ierr);
1113b3e256bSKris Buschelman   ierr = PetscMalloc((len+2)*sizeof(char),&name);CHKERRQ(ierr);
1123b3e256bSKris Buschelman   sprintf(name,"_%s",_A);
1133b3e256bSKris Buschelman   ierr = PetscObjectSetName((PetscObject)*F,name);CHKERRQ(ierr);
1143b3e256bSKris Buschelman   ierr = PetscFree(name);CHKERRQ(ierr);
1153b3e256bSKris Buschelman   PetscFunctionReturn(0);
1163b3e256bSKris Buschelman }
1173b3e256bSKris Buschelman 
1183b3e256bSKris Buschelman #undef __FUNCT__
11905db81ecSKris Buschelman #define __FUNCT__ "MatLUFactorSymbolic_Matlab"
120dfbe8321SBarry Smith PetscErrorCode MatLUFactorSymbolic_Matlab(Mat A,IS r,IS c,MatFactorInfo *info,Mat *F)
1213b3e256bSKris Buschelman {
122dfbe8321SBarry Smith   PetscErrorCode ierr;
1233b3e256bSKris Buschelman 
1243b3e256bSKris Buschelman   PetscFunctionBegin;
1252a4c71feSBarry Smith   if (A->cmap.N != A->rmap.N) SETERRQ(PETSC_ERR_ARG_SIZ,"matrix must be square");
1267adad957SLisandro Dalcin   ierr                       = MatCreate(((PetscObject)A)->comm,F);CHKERRQ(ierr);
1272a4c71feSBarry Smith   ierr                       = MatSetSizes(*F,A->rmap.n,A->cmap.n,A->rmap.n,A->cmap.n);CHKERRQ(ierr);
1287adad957SLisandro Dalcin   ierr                       = MatSetType(*F,((PetscObject)A)->type_name);CHKERRQ(ierr);
1293b3e256bSKris Buschelman   ierr                       = MatSeqAIJSetPreallocation(*F,0,PETSC_NULL);CHKERRQ(ierr);
13005db81ecSKris Buschelman   (*F)->ops->solve           = MatSolve_Matlab;
13105db81ecSKris Buschelman   (*F)->ops->lufactornumeric = MatLUFactorNumeric_Matlab;
132*5c9eb25fSBarry Smith   (*F)->factor               = MAT_FACTOR_LU;
1333b3e256bSKris Buschelman   PetscFunctionReturn(0);
1343b3e256bSKris Buschelman }
1353b3e256bSKris Buschelman 
1363b3e256bSKris Buschelman #undef __FUNCT__
137b24902e0SBarry Smith #define __FUNCT__ "MatGetFactor_seqaij_matlab"
138*5c9eb25fSBarry Smith PetscErrorCode MatGetFactor_seqaij_matlab(Mat A,MatFactorType ftype,Mat *F)
1393b3e256bSKris Buschelman {
140dfbe8321SBarry Smith   PetscErrorCode ierr;
1413b3e256bSKris Buschelman 
1423b3e256bSKris Buschelman   PetscFunctionBegin;
1432a4c71feSBarry Smith   if (A->cmap.N != A->rmap.N) SETERRQ(PETSC_ERR_ARG_SIZ,"matrix must be square");
1447adad957SLisandro Dalcin   ierr                        = MatCreate(((PetscObject)A)->comm,F);CHKERRQ(ierr);
1452a4c71feSBarry Smith   ierr                        = MatSetSizes(*F,A->rmap.n,A->cmap.n,A->rmap.n,A->cmap.n);CHKERRQ(ierr);
1467adad957SLisandro Dalcin   ierr                        = MatSetType(*F,((PetscObject)A)->type_name);CHKERRQ(ierr);
1473b3e256bSKris Buschelman   ierr                        = MatSeqAIJSetPreallocation(*F,0,PETSC_NULL);CHKERRQ(ierr);
148b24902e0SBarry Smith   (*F)->ops->solve            = MatSolve_Matlab;
149b24902e0SBarry Smith   (*F)->ops->lufactornumeric  = MatLUFactorNumeric_Matlab;
150b24902e0SBarry Smith   (*F)->ops->lufactorsymbolic = MatLUFactorSymbolic_Matlab;
151*5c9eb25fSBarry Smith   (*F)->factor                = MAT_FACTOR_LU;
1523b3e256bSKris Buschelman   PetscFunctionReturn(0);
1533b3e256bSKris Buschelman }
1543b3e256bSKris Buschelman 
155b24902e0SBarry Smith 
1563b3e256bSKris Buschelman /* --------------------------------------------------------------------------------*/
1573b3e256bSKris Buschelman #undef __FUNCT__
15805db81ecSKris Buschelman #define __FUNCT__ "MatILUDTFactor_Matlab"
1597529efd4SKris Buschelman PetscErrorCode MatILUDTFactor_Matlab(Mat A,IS isrow,IS iscol,MatFactorInfo *info,Mat *F)
1603b3e256bSKris Buschelman {
161dfbe8321SBarry Smith   PetscErrorCode ierr;
162de4209c5SBarry Smith   size_t         len;
1633b3e256bSKris Buschelman   char           *_A,*name;
1643b3e256bSKris Buschelman 
1653b3e256bSKris Buschelman   PetscFunctionBegin;
1663b3e256bSKris Buschelman   if (info->dt == PETSC_DEFAULT)      info->dt      = .005;
1673b3e256bSKris Buschelman   if (info->dtcol == PETSC_DEFAULT)   info->dtcol   = .01;
1682a4c71feSBarry Smith   if (A->cmap.N != A->rmap.N) SETERRQ(PETSC_ERR_ARG_SIZ,"matrix must be square");
1697adad957SLisandro Dalcin   ierr                       = MatCreate(((PetscObject)A)->comm,F);CHKERRQ(ierr);
1702a4c71feSBarry Smith   ierr                       = MatSetSizes(*F,A->rmap.n,A->cmap.n,A->rmap.n,A->cmap.n);CHKERRQ(ierr);
1717adad957SLisandro Dalcin   ierr                       = MatSetType(*F,((PetscObject)A)->type_name);CHKERRQ(ierr);
1723b3e256bSKris Buschelman   ierr                       = MatSeqAIJSetPreallocation(*F,0,PETSC_NULL);CHKERRQ(ierr);
173f365a357SKris Buschelman   (*F)->ops->solve           = MatSolve_Matlab;
174*5c9eb25fSBarry Smith   (*F)->factor               = MAT_FACTOR_LU;
1757adad957SLisandro Dalcin   ierr = PetscMatlabEnginePut(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),(PetscObject)A);CHKERRQ(ierr);
1763b3e256bSKris Buschelman   _A   = A->name;
1777adad957SLisandro Dalcin   ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),"info_%s = struct('droptol',%g,'thresh',%g);",_A,info->dt,info->dtcol);CHKERRQ(ierr);
1787adad957SLisandro Dalcin   ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),"[l_%s,u_%s,p_%s] = luinc(%s',info_%s);",_A,_A,_A,_A,_A);CHKERRQ(ierr);
1797adad957SLisandro Dalcin   ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),"%s = 0;",_A);CHKERRQ(ierr);
1803b3e256bSKris Buschelman 
1813b3e256bSKris Buschelman   ierr = PetscStrlen(_A,&len);CHKERRQ(ierr);
1823b3e256bSKris Buschelman   ierr = PetscMalloc((len+2)*sizeof(char),&name);CHKERRQ(ierr);
1833b3e256bSKris Buschelman   sprintf(name,"_%s",_A);
1843b3e256bSKris Buschelman   ierr = PetscObjectSetName((PetscObject)*F,name);CHKERRQ(ierr);
1853b3e256bSKris Buschelman   ierr = PetscFree(name);CHKERRQ(ierr);
1863b3e256bSKris Buschelman   PetscFunctionReturn(0);
1873b3e256bSKris Buschelman }
1883b3e256bSKris Buschelman 
18905db81ecSKris Buschelman #undef __FUNCT__
19005db81ecSKris Buschelman #define __FUNCT__ "MatFactorInfo_Matlab"
191dfbe8321SBarry Smith PetscErrorCode MatFactorInfo_Matlab(Mat A,PetscViewer viewer)
1923b3e256bSKris Buschelman {
193dfbe8321SBarry Smith   PetscErrorCode ierr;
1943b3e256bSKris Buschelman 
1953b3e256bSKris Buschelman   PetscFunctionBegin;
1963b3e256bSKris Buschelman   ierr = PetscViewerASCIIPrintf(viewer,"Matlab run parameters:  -- not written yet!\n");CHKERRQ(ierr);
1973b3e256bSKris Buschelman   PetscFunctionReturn(0);
1983b3e256bSKris Buschelman }
1993b3e256bSKris Buschelman 
2003b3e256bSKris Buschelman #undef __FUNCT__
20105db81ecSKris Buschelman #define __FUNCT__ "MatView_Matlab"
202b2d3331aSBarry Smith PetscErrorCode MatView_Matlab(Mat A,PetscViewer viewer)
203b2d3331aSBarry Smith {
204dfbe8321SBarry Smith   PetscErrorCode    ierr;
20532077d6dSBarry Smith   PetscTruth        iascii;
20605db81ecSKris Buschelman   PetscViewerFormat format;
20705db81ecSKris Buschelman   Mat_Matlab        *lu=(Mat_Matlab*)(A->spptr);
20805db81ecSKris Buschelman 
20905db81ecSKris Buschelman   PetscFunctionBegin;
210b24902e0SBarry Smith   ierr = MatView_SeqAIJ(A,viewer);CHKERRQ(ierr);
21132077d6dSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);CHKERRQ(ierr);
21232077d6dSBarry Smith   if (iascii) {
21305db81ecSKris Buschelman     ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
21405db81ecSKris Buschelman     if (format == PETSC_VIEWER_ASCII_FACTOR_INFO) {
21505db81ecSKris Buschelman       ierr = MatFactorInfo_Matlab(A,viewer);
21605db81ecSKris Buschelman     }
21705db81ecSKris Buschelman   }
21805db81ecSKris Buschelman   PetscFunctionReturn(0);
21905db81ecSKris Buschelman }
220f365a357SKris Buschelman 
22105db81ecSKris Buschelman 
22205db81ecSKris Buschelman /*MC
22305db81ecSKris Buschelman   MATMATLAB - MATMATLAB = "matlab" - A matrix type providing direct solvers (LU and QR) and drop tolerance
22405db81ecSKris Buschelman   based ILU factorization (ILUDT) for sequential matrices via the external package Matlab.
22505db81ecSKris Buschelman 
22605db81ecSKris Buschelman   If Matlab is instaled (see the manual for
22705db81ecSKris Buschelman   instructions on how to declare the existence of external packages),
22805db81ecSKris Buschelman   a matrix type can be constructed which invokes Matlab solvers.
22905db81ecSKris Buschelman   After calling MatCreate(...,A), simply call MatSetType(A,MATMATLAB).
23005db81ecSKris Buschelman   This matrix type is only supported for double precision real.
23105db81ecSKris Buschelman 
23205db81ecSKris Buschelman   This matrix inherits from MATSEQAIJ.  As a result, MatSeqAIJSetPreallocation is
23305db81ecSKris Buschelman   supported for this matrix type.  One can also call MatConvert for an inplace conversion to or from
23405db81ecSKris Buschelman   the MATSEQAIJ type without data copy.
23505db81ecSKris Buschelman 
23605db81ecSKris Buschelman   Options Database Keys:
23705db81ecSKris Buschelman + -mat_type matlab - sets the matrix type to "matlab" during a call to MatSetFromOptions()
23805db81ecSKris Buschelman - -mat_matlab_qr   - sets the direct solver to be QR instead of LU
23905db81ecSKris Buschelman 
24005db81ecSKris Buschelman   Level: beginner
24105db81ecSKris Buschelman 
24205db81ecSKris Buschelman .seealso: PCLU
24305db81ecSKris Buschelman M*/
24405db81ecSKris Buschelman 
245