xref: /petsc/src/mat/impls/aij/seq/matlab/aijmatlab.c (revision 156180f93dea4d21dd6e9f4080b1d1db64a8c6c0)
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;
24f0523c5fSHong Zhang   mat  = mxCreateSparse(B->cmap->n,B->rmap->n,aij->nz,mxREAL);
25f0523c5fSHong Zhang   //mat  = mxCreateSparse(((PetscObject)B)->cmap.n,((PetscObject)B)->rmap.n,((Mat_SeqAIJ*)aij)->nz,mxREAL);
26a1d52234SKris Buschelman   ierr = PetscMemcpy(mxGetPr(mat),aij->a,aij->nz*sizeof(PetscScalar));CHKERRQ(ierr);
27a1d52234SKris Buschelman   /* Matlab stores by column, not row so we pass in the transpose of the matrix */
28a1d52234SKris Buschelman   ierr = PetscMemcpy(mxGetIr(mat),aij->j,aij->nz*sizeof(int));CHKERRQ(ierr);
29f0523c5fSHong Zhang   ierr = PetscMemcpy(mxGetJc(mat),aij->i,(B->rmap->n+1)*sizeof(int));CHKERRQ(ierr);
30a1d52234SKris Buschelman 
31a1d52234SKris Buschelman   /* Matlab indices start at 0 for sparse (what a surprise) */
32a1d52234SKris Buschelman 
33a1d52234SKris Buschelman   ierr = PetscObjectName(obj);CHKERRQ(ierr);
34a1d52234SKris Buschelman   engPutVariable((Engine *)mengine,obj->name,mat);
35a1d52234SKris Buschelman   PetscFunctionReturn(0);
36a1d52234SKris Buschelman }
37a1d52234SKris Buschelman EXTERN_C_END
38a1d52234SKris Buschelman 
39a1d52234SKris Buschelman EXTERN_C_BEGIN
40a1d52234SKris Buschelman #undef __FUNCT__
41a1d52234SKris Buschelman #define __FUNCT__ "MatMatlabEngineGet_Matlab"
42be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatMatlabEngineGet_Matlab(PetscObject obj,void *mengine)
43a1d52234SKris Buschelman {
44dfbe8321SBarry Smith   PetscErrorCode ierr;
45dfbe8321SBarry Smith   int            ii;
46a1d52234SKris Buschelman   Mat            mat = (Mat)obj;
47a1d52234SKris Buschelman   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*)mat->data;
48a1d52234SKris Buschelman   mxArray        *mmat;
49a1d52234SKris Buschelman 
50a1d52234SKris Buschelman   PetscFunctionBegin;
511f03425eSSatish Balay   ierr = MatSeqXAIJFreeAIJ(mat,&aij->a,&aij->j,&aij->i);CHKERRQ(ierr);
52a1d52234SKris Buschelman 
53a1d52234SKris Buschelman   mmat = engGetVariable((Engine *)mengine,obj->name);
54a1d52234SKris Buschelman 
55f0523c5fSHong Zhang   aij->nz           = (mxGetJc(mmat))[mat->rmap->n];
56f0523c5fSHong Zhang   ierr  = PetscMalloc3(aij->nz,PetscScalar,&aij->a,aij->nz,PetscInt,&aij->j,mat->rmap->n+1,PetscInt,&aij->i);CHKERRQ(ierr);
57a1d52234SKris Buschelman   aij->singlemalloc = PETSC_TRUE;
58a1d52234SKris Buschelman 
59a1d52234SKris Buschelman   ierr = PetscMemcpy(aij->a,mxGetPr(mmat),aij->nz*sizeof(PetscScalar));CHKERRQ(ierr);
60a1d52234SKris Buschelman   /* Matlab stores by column, not row so we pass in the transpose of the matrix */
61a1d52234SKris Buschelman   ierr = PetscMemcpy(aij->j,mxGetIr(mmat),aij->nz*sizeof(int));CHKERRQ(ierr);
62f0523c5fSHong Zhang   ierr = PetscMemcpy(aij->i,mxGetJc(mmat),(mat->rmap->n+1)*sizeof(int));CHKERRQ(ierr);
63a1d52234SKris Buschelman 
64f0523c5fSHong Zhang   for (ii=0; ii<mat->rmap->n; ii++) {
65a1d52234SKris Buschelman     aij->ilen[ii] = aij->imax[ii] = aij->i[ii+1] - aij->i[ii];
66a1d52234SKris Buschelman   }
67a1d52234SKris Buschelman 
68a1d52234SKris Buschelman   ierr = MatAssemblyBegin(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
69a1d52234SKris Buschelman   ierr = MatAssemblyEnd(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
70a1d52234SKris Buschelman 
71a1d52234SKris Buschelman   PetscFunctionReturn(0);
72a1d52234SKris Buschelman }
73a1d52234SKris Buschelman EXTERN_C_END
74a1d52234SKris Buschelman 
7505db81ecSKris Buschelman #undef __FUNCT__
7605db81ecSKris Buschelman #define __FUNCT__ "MatSolve_Matlab"
77dfbe8321SBarry Smith PetscErrorCode MatSolve_Matlab(Mat A,Vec b,Vec x)
783b3e256bSKris Buschelman {
79dfbe8321SBarry Smith   PetscErrorCode ierr;
80e060cb09SBarry Smith   const char     *_A,*_b,*_x;
813b3e256bSKris Buschelman 
823b3e256bSKris Buschelman   PetscFunctionBegin;
833b3e256bSKris Buschelman   /* make sure objects have names; use default if not */
843b3e256bSKris Buschelman   ierr = PetscObjectName((PetscObject)b);CHKERRQ(ierr);
853b3e256bSKris Buschelman   ierr = PetscObjectName((PetscObject)x);CHKERRQ(ierr);
863b3e256bSKris Buschelman 
873b3e256bSKris Buschelman   ierr = PetscObjectGetName((PetscObject)A,&_A);CHKERRQ(ierr);
883b3e256bSKris Buschelman   ierr = PetscObjectGetName((PetscObject)b,&_b);CHKERRQ(ierr);
893b3e256bSKris Buschelman   ierr = PetscObjectGetName((PetscObject)x,&_x);CHKERRQ(ierr);
907adad957SLisandro Dalcin   ierr = PetscMatlabEnginePut(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),(PetscObject)b);CHKERRQ(ierr);
917adad957SLisandro Dalcin   ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),"%s = u%s\\(l%s\\(p%s*%s));",_x,_A,_A,_A,_b);CHKERRQ(ierr);
927adad957SLisandro Dalcin   ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),"%s = 0;",_b);CHKERRQ(ierr);
937adad957SLisandro Dalcin   /* ierr = PetscMatlabEnginePrintOutput(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),stdout);CHKERRQ(ierr);  */
947adad957SLisandro Dalcin   ierr = PetscMatlabEngineGet(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),(PetscObject)x);CHKERRQ(ierr);
953b3e256bSKris Buschelman   PetscFunctionReturn(0);
963b3e256bSKris Buschelman }
973b3e256bSKris Buschelman 
983b3e256bSKris Buschelman #undef __FUNCT__
9905db81ecSKris Buschelman #define __FUNCT__ "MatLUFactorNumeric_Matlab"
1000481f469SBarry Smith PetscErrorCode MatLUFactorNumeric_Matlab(Mat F,Mat A,const MatFactorInfo *info)
1013b3e256bSKris Buschelman {
102dfbe8321SBarry Smith   PetscErrorCode ierr;
103de4209c5SBarry Smith   size_t         len;
1043b3e256bSKris Buschelman   char           *_A,*name;
1053b3e256bSKris Buschelman 
1063b3e256bSKris Buschelman   PetscFunctionBegin;
1077adad957SLisandro Dalcin   ierr = PetscMatlabEnginePut(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),(PetscObject)A);CHKERRQ(ierr);
108f0523c5fSHong Zhang   _A   = ((PetscObject)A)->name;
1097adad957SLisandro 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);
1107adad957SLisandro Dalcin   ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),"%s = 0;",_A);CHKERRQ(ierr);
1113b3e256bSKris Buschelman   ierr = PetscStrlen(_A,&len);CHKERRQ(ierr);
1123b3e256bSKris Buschelman   ierr = PetscMalloc((len+2)*sizeof(char),&name);CHKERRQ(ierr);
1133b3e256bSKris Buschelman   sprintf(name,"_%s",_A);
114f0523c5fSHong Zhang   ierr = PetscObjectSetName((PetscObject)F,name);CHKERRQ(ierr);
1153b3e256bSKris Buschelman   ierr = PetscFree(name);CHKERRQ(ierr);
116f0523c5fSHong Zhang   F->ops->solve              = MatSolve_Matlab;
1173b3e256bSKris Buschelman   PetscFunctionReturn(0);
1183b3e256bSKris Buschelman }
1193b3e256bSKris Buschelman 
1203b3e256bSKris Buschelman #undef __FUNCT__
12105db81ecSKris Buschelman #define __FUNCT__ "MatLUFactorSymbolic_Matlab"
1220481f469SBarry Smith PetscErrorCode MatLUFactorSymbolic_Matlab(Mat F,Mat A,IS r,IS c,const MatFactorInfo *info)
1233b3e256bSKris Buschelman {
1243b3e256bSKris Buschelman   PetscFunctionBegin;
125f0523c5fSHong Zhang   if (A->cmap->N != A->rmap->N) SETERRQ(PETSC_ERR_ARG_SIZ,"matrix must be square");
126f0523c5fSHong Zhang   F->ops->lufactornumeric    = MatLUFactorNumeric_Matlab;
1273b3e256bSKris Buschelman   PetscFunctionReturn(0);
1283b3e256bSKris Buschelman }
1293b3e256bSKris Buschelman 
1303b3e256bSKris Buschelman #undef __FUNCT__
131b24902e0SBarry Smith #define __FUNCT__ "MatGetFactor_seqaij_matlab"
1325c9eb25fSBarry Smith PetscErrorCode MatGetFactor_seqaij_matlab(Mat A,MatFactorType ftype,Mat *F)
1333b3e256bSKris Buschelman {
134dfbe8321SBarry Smith   PetscErrorCode ierr;
1353b3e256bSKris Buschelman 
1363b3e256bSKris Buschelman   PetscFunctionBegin;
137f0523c5fSHong Zhang   if (A->cmap->N != A->rmap->N) SETERRQ(PETSC_ERR_ARG_SIZ,"matrix must be square");
1387adad957SLisandro Dalcin   ierr                        = MatCreate(((PetscObject)A)->comm,F);CHKERRQ(ierr);
139f0523c5fSHong Zhang   ierr                        = MatSetSizes(*F,A->rmap->n,A->cmap->n,A->rmap->n,A->cmap->n);CHKERRQ(ierr);
1407adad957SLisandro Dalcin   ierr                        = MatSetType(*F,((PetscObject)A)->type_name);CHKERRQ(ierr);
1413b3e256bSKris Buschelman   ierr                        = MatSeqAIJSetPreallocation(*F,0,PETSC_NULL);CHKERRQ(ierr);
142b24902e0SBarry Smith   (*F)->ops->lufactorsymbolic = MatLUFactorSymbolic_Matlab;
143f0523c5fSHong Zhang 
1445c9eb25fSBarry Smith   (*F)->factor                = MAT_FACTOR_LU;
1453b3e256bSKris Buschelman   PetscFunctionReturn(0);
1463b3e256bSKris Buschelman }
1473b3e256bSKris Buschelman 
148b24902e0SBarry Smith 
1493b3e256bSKris Buschelman /* --------------------------------------------------------------------------------*/
1503b3e256bSKris Buschelman #undef __FUNCT__
15105db81ecSKris Buschelman #define __FUNCT__ "MatILUDTFactor_Matlab"
152*156180f9SHong Zhang PetscErrorCode MatILUDTFactor_Matlab(Mat A,IS isrow,IS iscol,const MatFactorInfo *info)
1533b3e256bSKris Buschelman {
154dfbe8321SBarry Smith   PetscErrorCode ierr;
155de4209c5SBarry Smith   size_t         len;
1563b3e256bSKris Buschelman   char           *_A,*name;
157*156180f9SHong Zhang   PetscReal      dt,dtcol;
158*156180f9SHong Zhang   Mat            F;
1593b3e256bSKris Buschelman 
1603b3e256bSKris Buschelman   PetscFunctionBegin;
161*156180f9SHong Zhang   if (info->dt == PETSC_DEFAULT)      dt    = .005;
162*156180f9SHong Zhang   if (info->dtcol == PETSC_DEFAULT)   dtcol = .01;
163*156180f9SHong Zhang   ierr = MatGetFactor(A,MAT_SOLVER_MATLAB,MAT_FACTOR_ILU,&F);CHKERRQ(ierr);
164*156180f9SHong Zhang   F->ops->solve           = MatSolve_Matlab;
165*156180f9SHong Zhang   F->factor               = MAT_FACTOR_LU;
1667adad957SLisandro Dalcin   ierr = PetscMatlabEnginePut(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),(PetscObject)A);CHKERRQ(ierr);
167f0523c5fSHong Zhang   _A   = ((PetscObject)A)->name;
168*156180f9SHong Zhang   ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),"info_%s = struct('droptol',%g,'thresh',%g);",_A,dt,dtcol);CHKERRQ(ierr);
1697adad957SLisandro 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);
1707adad957SLisandro Dalcin   ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),"%s = 0;",_A);CHKERRQ(ierr);
1713b3e256bSKris Buschelman 
1723b3e256bSKris Buschelman   ierr = PetscStrlen(_A,&len);CHKERRQ(ierr);
1733b3e256bSKris Buschelman   ierr = PetscMalloc((len+2)*sizeof(char),&name);CHKERRQ(ierr);
1743b3e256bSKris Buschelman   sprintf(name,"_%s",_A);
175*156180f9SHong Zhang   ierr = PetscObjectSetName((PetscObject)F,name);CHKERRQ(ierr);
1763b3e256bSKris Buschelman   ierr = PetscFree(name);CHKERRQ(ierr);
1773b3e256bSKris Buschelman   PetscFunctionReturn(0);
1783b3e256bSKris Buschelman }
1793b3e256bSKris Buschelman 
18005db81ecSKris Buschelman #undef __FUNCT__
18105db81ecSKris Buschelman #define __FUNCT__ "MatFactorInfo_Matlab"
182dfbe8321SBarry Smith PetscErrorCode MatFactorInfo_Matlab(Mat A,PetscViewer viewer)
1833b3e256bSKris Buschelman {
184dfbe8321SBarry Smith   PetscErrorCode ierr;
1853b3e256bSKris Buschelman 
1863b3e256bSKris Buschelman   PetscFunctionBegin;
1873b3e256bSKris Buschelman   ierr = PetscViewerASCIIPrintf(viewer,"Matlab run parameters:  -- not written yet!\n");CHKERRQ(ierr);
1883b3e256bSKris Buschelman   PetscFunctionReturn(0);
1893b3e256bSKris Buschelman }
1903b3e256bSKris Buschelman 
1913b3e256bSKris Buschelman #undef __FUNCT__
19205db81ecSKris Buschelman #define __FUNCT__ "MatView_Matlab"
193b2d3331aSBarry Smith PetscErrorCode MatView_Matlab(Mat A,PetscViewer viewer)
194b2d3331aSBarry Smith {
195dfbe8321SBarry Smith   PetscErrorCode    ierr;
19632077d6dSBarry Smith   PetscTruth        iascii;
19705db81ecSKris Buschelman   PetscViewerFormat format;
19805db81ecSKris Buschelman 
19905db81ecSKris Buschelman   PetscFunctionBegin;
200b24902e0SBarry Smith   ierr = MatView_SeqAIJ(A,viewer);CHKERRQ(ierr);
20132077d6dSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);CHKERRQ(ierr);
20232077d6dSBarry Smith   if (iascii) {
20305db81ecSKris Buschelman     ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
20405db81ecSKris Buschelman     if (format == PETSC_VIEWER_ASCII_FACTOR_INFO) {
20505db81ecSKris Buschelman       ierr = MatFactorInfo_Matlab(A,viewer);
20605db81ecSKris Buschelman     }
20705db81ecSKris Buschelman   }
20805db81ecSKris Buschelman   PetscFunctionReturn(0);
20905db81ecSKris Buschelman }
210f365a357SKris Buschelman 
21105db81ecSKris Buschelman 
21205db81ecSKris Buschelman /*MC
21305db81ecSKris Buschelman   MATMATLAB - MATMATLAB = "matlab" - A matrix type providing direct solvers (LU and QR) and drop tolerance
21405db81ecSKris Buschelman   based ILU factorization (ILUDT) for sequential matrices via the external package Matlab.
21505db81ecSKris Buschelman 
21605db81ecSKris Buschelman   If Matlab is instaled (see the manual for
21705db81ecSKris Buschelman   instructions on how to declare the existence of external packages),
21805db81ecSKris Buschelman   a matrix type can be constructed which invokes Matlab solvers.
21905db81ecSKris Buschelman   After calling MatCreate(...,A), simply call MatSetType(A,MATMATLAB).
22005db81ecSKris Buschelman   This matrix type is only supported for double precision real.
22105db81ecSKris Buschelman 
22205db81ecSKris Buschelman   This matrix inherits from MATSEQAIJ.  As a result, MatSeqAIJSetPreallocation is
22305db81ecSKris Buschelman   supported for this matrix type.  One can also call MatConvert for an inplace conversion to or from
22405db81ecSKris Buschelman   the MATSEQAIJ type without data copy.
22505db81ecSKris Buschelman 
22605db81ecSKris Buschelman   Options Database Keys:
22705db81ecSKris Buschelman + -mat_type matlab - sets the matrix type to "matlab" during a call to MatSetFromOptions()
22805db81ecSKris Buschelman - -mat_matlab_qr   - sets the direct solver to be QR instead of LU
22905db81ecSKris Buschelman 
23005db81ecSKris Buschelman   Level: beginner
23105db81ecSKris Buschelman 
23205db81ecSKris Buschelman .seealso: PCLU
23305db81ecSKris Buschelman M*/
23405db81ecSKris Buschelman 
235