xref: /petsc/src/mat/impls/aij/seq/matlab/aijmatlab.c (revision a7bb0f050e5fa364a9a9e10a619fef493f2d1df0)
1be1d678aSKris Buschelman #define PETSCMAT_DLL
2be1d678aSKris Buschelman 
33b3e256bSKris Buschelman /*
43b3e256bSKris Buschelman         Provides an interface for the Matlab engine sparse solver
53b3e256bSKris Buschelman 
63b3e256bSKris Buschelman */
77c4f633dSBarry Smith #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__
15b3866ffcSBarry Smith #define __FUNCT__ "MatlabEnginePut_SeqAIJ"
16b3866ffcSBarry Smith PetscErrorCode PETSCMAT_DLLEXPORT MatlabEnginePut_SeqAIJ(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__
41*a7bb0f05SBarry Smith #define __FUNCT__ "MatSeqAIJFromMatlab"
42*a7bb0f05SBarry Smith /*@
43*a7bb0f05SBarry Smith     MatSeqAIJFromMatlab - Given a Matlab sparse matrix, fills a SeqAIJ matrix with its transpose.
44*a7bb0f05SBarry Smith 
45*a7bb0f05SBarry Smith    Not Collective
46*a7bb0f05SBarry Smith 
47*a7bb0f05SBarry Smith    Input Parameters:
48*a7bb0f05SBarry Smith +     mmat - a Matlab sparse matris
49*a7bb0f05SBarry Smith -     mat - a already created MATSEQAIJ
50*a7bb0f05SBarry Smith 
51*a7bb0f05SBarry Smith @*/
52*a7bb0f05SBarry Smith PetscErrorCode PETSCMAT_DLLEXPORT MatSeqAIJFromMatlab(mxArray *mmat,Mat mat)
53a1d52234SKris Buschelman {
54dfbe8321SBarry Smith   PetscErrorCode ierr;
55dfbe8321SBarry Smith   int            ii;
56a1d52234SKris Buschelman   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*)mat->data;
57a1d52234SKris Buschelman 
58a1d52234SKris Buschelman   PetscFunctionBegin;
591f03425eSSatish Balay   ierr = MatSeqXAIJFreeAIJ(mat,&aij->a,&aij->j,&aij->i);CHKERRQ(ierr);
60a1d52234SKris Buschelman 
61f0523c5fSHong Zhang   aij->nz           = (mxGetJc(mmat))[mat->rmap->n];
62f0523c5fSHong Zhang   ierr  = PetscMalloc3(aij->nz,PetscScalar,&aij->a,aij->nz,PetscInt,&aij->j,mat->rmap->n+1,PetscInt,&aij->i);CHKERRQ(ierr);
63a1d52234SKris Buschelman   aij->singlemalloc = PETSC_TRUE;
64a1d52234SKris Buschelman 
65a1d52234SKris Buschelman   ierr = PetscMemcpy(aij->a,mxGetPr(mmat),aij->nz*sizeof(PetscScalar));CHKERRQ(ierr);
66a1d52234SKris Buschelman   /* Matlab stores by column, not row so we pass in the transpose of the matrix */
67a1d52234SKris Buschelman   ierr = PetscMemcpy(aij->j,mxGetIr(mmat),aij->nz*sizeof(int));CHKERRQ(ierr);
68f0523c5fSHong Zhang   ierr = PetscMemcpy(aij->i,mxGetJc(mmat),(mat->rmap->n+1)*sizeof(int));CHKERRQ(ierr);
69a1d52234SKris Buschelman 
70f0523c5fSHong Zhang   for (ii=0; ii<mat->rmap->n; ii++) {
71a1d52234SKris Buschelman     aij->ilen[ii] = aij->imax[ii] = aij->i[ii+1] - aij->i[ii];
72a1d52234SKris Buschelman   }
73a1d52234SKris Buschelman 
74a1d52234SKris Buschelman   ierr = MatAssemblyBegin(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
75a1d52234SKris Buschelman   ierr = MatAssemblyEnd(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
76*a7bb0f05SBarry Smith   PetscFunctionReturn(0);
77*a7bb0f05SBarry Smith }
78*a7bb0f05SBarry Smith EXTERN_C_END
79a1d52234SKris Buschelman 
80*a7bb0f05SBarry Smith 
81*a7bb0f05SBarry Smith EXTERN_C_BEGIN
82*a7bb0f05SBarry Smith #undef __FUNCT__
83*a7bb0f05SBarry Smith #define __FUNCT__ "MatlabEngineGet_SeqAIJ"
84*a7bb0f05SBarry Smith PetscErrorCode PETSCMAT_DLLEXPORT MatlabEngineGet_SeqAIJ(PetscObject obj,void *mengine)
85*a7bb0f05SBarry Smith {
86*a7bb0f05SBarry Smith   PetscErrorCode ierr;
87*a7bb0f05SBarry Smith   Mat            mat = (Mat)obj;
88*a7bb0f05SBarry Smith   mxArray        *mmat;
89*a7bb0f05SBarry Smith 
90*a7bb0f05SBarry Smith   PetscFunctionBegin;
91*a7bb0f05SBarry Smith   mmat = engGetVariable((Engine *)mengine,obj->name);
92*a7bb0f05SBarry Smith   ierr = MatSeqAIJFromMatlab(mmat,mat);CHKERRQ(ierr);
93a1d52234SKris Buschelman   PetscFunctionReturn(0);
94a1d52234SKris Buschelman }
95a1d52234SKris Buschelman EXTERN_C_END
96a1d52234SKris Buschelman 
9705db81ecSKris Buschelman #undef __FUNCT__
9805db81ecSKris Buschelman #define __FUNCT__ "MatSolve_Matlab"
99dfbe8321SBarry Smith PetscErrorCode MatSolve_Matlab(Mat A,Vec b,Vec x)
1003b3e256bSKris Buschelman {
101dfbe8321SBarry Smith   PetscErrorCode ierr;
102e060cb09SBarry Smith   const char     *_A,*_b,*_x;
1033b3e256bSKris Buschelman 
1043b3e256bSKris Buschelman   PetscFunctionBegin;
1053b3e256bSKris Buschelman   /* make sure objects have names; use default if not */
1063b3e256bSKris Buschelman   ierr = PetscObjectName((PetscObject)b);CHKERRQ(ierr);
1073b3e256bSKris Buschelman   ierr = PetscObjectName((PetscObject)x);CHKERRQ(ierr);
1083b3e256bSKris Buschelman 
1093b3e256bSKris Buschelman   ierr = PetscObjectGetName((PetscObject)A,&_A);CHKERRQ(ierr);
1103b3e256bSKris Buschelman   ierr = PetscObjectGetName((PetscObject)b,&_b);CHKERRQ(ierr);
1113b3e256bSKris Buschelman   ierr = PetscObjectGetName((PetscObject)x,&_x);CHKERRQ(ierr);
1127adad957SLisandro Dalcin   ierr = PetscMatlabEnginePut(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),(PetscObject)b);CHKERRQ(ierr);
1137adad957SLisandro Dalcin   ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),"%s = u%s\\(l%s\\(p%s*%s));",_x,_A,_A,_A,_b);CHKERRQ(ierr);
1147adad957SLisandro Dalcin   ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),"%s = 0;",_b);CHKERRQ(ierr);
1157adad957SLisandro Dalcin   /* ierr = PetscMatlabEnginePrintOutput(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),stdout);CHKERRQ(ierr);  */
1167adad957SLisandro Dalcin   ierr = PetscMatlabEngineGet(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),(PetscObject)x);CHKERRQ(ierr);
1173b3e256bSKris Buschelman   PetscFunctionReturn(0);
1183b3e256bSKris Buschelman }
1193b3e256bSKris Buschelman 
1203b3e256bSKris Buschelman #undef __FUNCT__
12105db81ecSKris Buschelman #define __FUNCT__ "MatLUFactorNumeric_Matlab"
1220481f469SBarry Smith PetscErrorCode MatLUFactorNumeric_Matlab(Mat F,Mat A,const MatFactorInfo *info)
1233b3e256bSKris Buschelman {
124dfbe8321SBarry Smith   PetscErrorCode ierr;
125de4209c5SBarry Smith   size_t         len;
1263b3e256bSKris Buschelman   char           *_A,*name;
127b3866ffcSBarry Smith   PetscReal      dtcol = info->dtcol;
1283b3e256bSKris Buschelman 
1293b3e256bSKris Buschelman   PetscFunctionBegin;
130d5f3da31SBarry Smith   if (F->factortype == MAT_FACTOR_ILU || info->dt > 0) {
131b3866ffcSBarry Smith     if (info->dtcol == PETSC_DEFAULT)  dtcol = .01;
132fe97e370SBarry Smith     F->ops->solve           = MatSolve_Matlab;
133d5f3da31SBarry Smith     F->factortype           = MAT_FACTOR_LU;
134fe97e370SBarry Smith     ierr = PetscMatlabEnginePut(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),(PetscObject)A);CHKERRQ(ierr);
135fe97e370SBarry Smith     _A   = ((PetscObject)A)->name;
136b3866ffcSBarry Smith     ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),"info_%s = struct('droptol',%g,'thresh',%g);",_A,info->dt,dtcol);CHKERRQ(ierr);
137fe97e370SBarry Smith     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);
138fe97e370SBarry Smith     ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),"%s = 0;",_A);CHKERRQ(ierr);
139fe97e370SBarry Smith 
140fe97e370SBarry Smith     ierr = PetscStrlen(_A,&len);CHKERRQ(ierr);
141fe97e370SBarry Smith     ierr = PetscMalloc((len+2)*sizeof(char),&name);CHKERRQ(ierr);
142fe97e370SBarry Smith     sprintf(name,"_%s",_A);
143fe97e370SBarry Smith     ierr = PetscObjectSetName((PetscObject)F,name);CHKERRQ(ierr);
144fe97e370SBarry Smith     ierr = PetscFree(name);CHKERRQ(ierr);
145fe97e370SBarry Smith   } else {
1467adad957SLisandro Dalcin     ierr = PetscMatlabEnginePut(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),(PetscObject)A);CHKERRQ(ierr);
147f0523c5fSHong Zhang     _A   = ((PetscObject)A)->name;
148b3866ffcSBarry Smith     ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),"[l_%s,u_%s,p_%s] = lu(%s',%g);",_A,_A,_A,_A,dtcol);CHKERRQ(ierr);
1497adad957SLisandro Dalcin     ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),"%s = 0;",_A);CHKERRQ(ierr);
1503b3e256bSKris Buschelman     ierr = PetscStrlen(_A,&len);CHKERRQ(ierr);
1513b3e256bSKris Buschelman     ierr = PetscMalloc((len+2)*sizeof(char),&name);CHKERRQ(ierr);
1523b3e256bSKris Buschelman     sprintf(name,"_%s",_A);
153f0523c5fSHong Zhang     ierr = PetscObjectSetName((PetscObject)F,name);CHKERRQ(ierr);
1543b3e256bSKris Buschelman     ierr = PetscFree(name);CHKERRQ(ierr);
155f0523c5fSHong Zhang     F->ops->solve              = MatSolve_Matlab;
156fe97e370SBarry Smith   }
1573b3e256bSKris Buschelman   PetscFunctionReturn(0);
1583b3e256bSKris Buschelman }
1593b3e256bSKris Buschelman 
1603b3e256bSKris Buschelman #undef __FUNCT__
16105db81ecSKris Buschelman #define __FUNCT__ "MatLUFactorSymbolic_Matlab"
1620481f469SBarry Smith PetscErrorCode MatLUFactorSymbolic_Matlab(Mat F,Mat A,IS r,IS c,const MatFactorInfo *info)
1633b3e256bSKris Buschelman {
1643b3e256bSKris Buschelman   PetscFunctionBegin;
165e32f2f54SBarry Smith   if (A->cmap->N != A->rmap->N) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"matrix must be square");
166f0523c5fSHong Zhang   F->ops->lufactornumeric    = MatLUFactorNumeric_Matlab;
167b3866ffcSBarry Smith   F->assembled = PETSC_TRUE;
1683b3e256bSKris Buschelman   PetscFunctionReturn(0);
1693b3e256bSKris Buschelman }
1703b3e256bSKris Buschelman 
17135bd34faSBarry Smith EXTERN_C_BEGIN
17235bd34faSBarry Smith #undef __FUNCT__
17335bd34faSBarry Smith #define __FUNCT__ "MatFactorGetSolverPackage_seqaij_matlab"
17435bd34faSBarry Smith PetscErrorCode MatFactorGetSolverPackage_seqaij_matlab(Mat A,const MatSolverPackage *type)
17535bd34faSBarry Smith {
17635bd34faSBarry Smith   PetscFunctionBegin;
1772692d6eeSBarry Smith   *type = MATSOLVERMATLAB;
17835bd34faSBarry Smith   PetscFunctionReturn(0);
17935bd34faSBarry Smith }
18035bd34faSBarry Smith EXTERN_C_END
18135bd34faSBarry Smith 
1823b3e256bSKris Buschelman #undef __FUNCT__
183b24902e0SBarry Smith #define __FUNCT__ "MatGetFactor_seqaij_matlab"
1845c9eb25fSBarry Smith PetscErrorCode MatGetFactor_seqaij_matlab(Mat A,MatFactorType ftype,Mat *F)
1853b3e256bSKris Buschelman {
186dfbe8321SBarry Smith   PetscErrorCode ierr;
1873b3e256bSKris Buschelman 
1883b3e256bSKris Buschelman   PetscFunctionBegin;
189e32f2f54SBarry Smith   if (A->cmap->N != A->rmap->N) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"matrix must be square");
1907adad957SLisandro Dalcin   ierr                         = MatCreate(((PetscObject)A)->comm,F);CHKERRQ(ierr);
191f0523c5fSHong Zhang   ierr                         = MatSetSizes(*F,A->rmap->n,A->cmap->n,A->rmap->n,A->cmap->n);CHKERRQ(ierr);
1927adad957SLisandro Dalcin   ierr                         = MatSetType(*F,((PetscObject)A)->type_name);CHKERRQ(ierr);
1933b3e256bSKris Buschelman   ierr                         = MatSeqAIJSetPreallocation(*F,0,PETSC_NULL);CHKERRQ(ierr);
194b24902e0SBarry Smith   (*F)->ops->lufactorsymbolic  = MatLUFactorSymbolic_Matlab;
195b3866ffcSBarry Smith   (*F)->ops->ilufactorsymbolic = MatLUFactorSymbolic_Matlab;
196f75d6de4SMatthew Knepley   ierr = PetscObjectComposeFunctionDynamic((PetscObject)(*F),"MatFactorGetSolverPackage_C","MatFactorGetSolverPackage_seqaij_matlab",MatFactorGetSolverPackage_seqaij_matlab);CHKERRQ(ierr);
197f0523c5fSHong Zhang 
198d5f3da31SBarry Smith   (*F)->factortype             = ftype;
1993b3e256bSKris Buschelman   PetscFunctionReturn(0);
2003b3e256bSKris Buschelman }
2013b3e256bSKris Buschelman 
202b24902e0SBarry Smith 
2033b3e256bSKris Buschelman /* --------------------------------------------------------------------------------*/
2043b3e256bSKris Buschelman 
20505db81ecSKris Buschelman #undef __FUNCT__
20605db81ecSKris Buschelman #define __FUNCT__ "MatFactorInfo_Matlab"
207dfbe8321SBarry Smith PetscErrorCode MatFactorInfo_Matlab(Mat A,PetscViewer viewer)
2083b3e256bSKris Buschelman {
209dfbe8321SBarry Smith   PetscErrorCode ierr;
2103b3e256bSKris Buschelman 
2113b3e256bSKris Buschelman   PetscFunctionBegin;
2123b3e256bSKris Buschelman   ierr = PetscViewerASCIIPrintf(viewer,"Matlab run parameters:  -- not written yet!\n");CHKERRQ(ierr);
2133b3e256bSKris Buschelman   PetscFunctionReturn(0);
2143b3e256bSKris Buschelman }
2153b3e256bSKris Buschelman 
2163b3e256bSKris Buschelman #undef __FUNCT__
21705db81ecSKris Buschelman #define __FUNCT__ "MatView_Matlab"
218b2d3331aSBarry Smith PetscErrorCode MatView_Matlab(Mat A,PetscViewer viewer)
219b2d3331aSBarry Smith {
220dfbe8321SBarry Smith   PetscErrorCode    ierr;
221ace3abfcSBarry Smith   PetscBool         iascii;
22205db81ecSKris Buschelman   PetscViewerFormat format;
22305db81ecSKris Buschelman 
22405db81ecSKris Buschelman   PetscFunctionBegin;
225b24902e0SBarry Smith   ierr = MatView_SeqAIJ(A,viewer);CHKERRQ(ierr);
2262692d6eeSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
22732077d6dSBarry Smith   if (iascii) {
22805db81ecSKris Buschelman     ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
22905db81ecSKris Buschelman     if (format == PETSC_VIEWER_ASCII_FACTOR_INFO) {
23005db81ecSKris Buschelman       ierr = MatFactorInfo_Matlab(A,viewer);
23105db81ecSKris Buschelman     }
23205db81ecSKris Buschelman   }
23305db81ecSKris Buschelman   PetscFunctionReturn(0);
23405db81ecSKris Buschelman }
235f365a357SKris Buschelman 
23605db81ecSKris Buschelman 
23705db81ecSKris Buschelman /*MC
2382692d6eeSBarry Smith   MATSOLVERMATLAB - "matlab" - Providing direct solvers (LU and QR) and drop tolerance
23905db81ecSKris Buschelman   based ILU factorization (ILUDT) for sequential matrices via the external package Matlab.
24005db81ecSKris Buschelman 
24105db81ecSKris Buschelman 
24241c8de11SBarry Smith   Works with MATSEQAIJ matrices.
24305db81ecSKris Buschelman 
24405db81ecSKris Buschelman   Options Database Keys:
24541c8de11SBarry Smith . -pc_factor_mat_solver_type matlab - selects Matlab to do the sparse factorization
24641c8de11SBarry Smith 
24705db81ecSKris Buschelman 
24805db81ecSKris Buschelman   Level: beginner
24905db81ecSKris Buschelman 
25005db81ecSKris Buschelman .seealso: PCLU
25141c8de11SBarry Smith 
25241c8de11SBarry Smith .seealso: PCFactorSetMatSolverPackage(), MatSolverPackage
25305db81ecSKris Buschelman M*/
25405db81ecSKris Buschelman 
255