xref: /petsc/src/mat/impls/aij/seq/matlab/aijmatlab.c (revision d32f9abdbc052d6e1fd06679b17a55415c3aae30)
1 #define PETSCMAT_DLL
2 
3 /*
4         Provides an interface for the Matlab engine sparse solver
5 
6 */
7 #include "src/mat/impls/aij/seq/aij.h"
8 
9 #include "engine.h"   /* Matlab include file */
10 #include "mex.h"      /* Matlab include file */
11 
12 
13 EXTERN_C_BEGIN
14 #undef __FUNCT__
15 #define __FUNCT__ "MatMatlabEnginePut_Matlab"
16 PetscErrorCode PETSCMAT_DLLEXPORT MatMatlabEnginePut_Matlab(PetscObject obj,void *mengine)
17 {
18   PetscErrorCode ierr;
19   Mat            B = (Mat)obj;
20   mxArray        *mat;
21   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*)B->data;
22 
23   PetscFunctionBegin;
24   mat  = mxCreateSparse(B->cmap.n,B->rmap.n,aij->nz,mxREAL);
25   ierr = PetscMemcpy(mxGetPr(mat),aij->a,aij->nz*sizeof(PetscScalar));CHKERRQ(ierr);
26   /* Matlab stores by column, not row so we pass in the transpose of the matrix */
27   ierr = PetscMemcpy(mxGetIr(mat),aij->j,aij->nz*sizeof(int));CHKERRQ(ierr);
28   ierr = PetscMemcpy(mxGetJc(mat),aij->i,(B->rmap.n+1)*sizeof(int));CHKERRQ(ierr);
29 
30   /* Matlab indices start at 0 for sparse (what a surprise) */
31 
32   ierr = PetscObjectName(obj);CHKERRQ(ierr);
33   engPutVariable((Engine *)mengine,obj->name,mat);
34   PetscFunctionReturn(0);
35 }
36 EXTERN_C_END
37 
38 EXTERN_C_BEGIN
39 #undef __FUNCT__
40 #define __FUNCT__ "MatMatlabEngineGet_Matlab"
41 PetscErrorCode PETSCMAT_DLLEXPORT MatMatlabEngineGet_Matlab(PetscObject obj,void *mengine)
42 {
43   PetscErrorCode ierr;
44   int            ii;
45   Mat            mat = (Mat)obj;
46   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*)mat->data;
47   mxArray        *mmat;
48 
49   PetscFunctionBegin;
50   ierr = MatSeqXAIJFreeAIJ(mat,&aij->a,&aij->j,&aij->i);CHKERRQ(ierr);
51 
52   mmat = engGetVariable((Engine *)mengine,obj->name);
53 
54   aij->nz           = (mxGetJc(mmat))[mat->rmap.n];
55   ierr  = PetscMalloc3(aij->nz,PetscScalar,&aij->a,aij->nz,PetscInt,&aij->j,mat->rmap.n+1,PetscInt,&aij->i);CHKERRQ(ierr);
56   aij->singlemalloc = PETSC_TRUE;
57 
58   ierr = PetscMemcpy(aij->a,mxGetPr(mmat),aij->nz*sizeof(PetscScalar));CHKERRQ(ierr);
59   /* Matlab stores by column, not row so we pass in the transpose of the matrix */
60   ierr = PetscMemcpy(aij->j,mxGetIr(mmat),aij->nz*sizeof(int));CHKERRQ(ierr);
61   ierr = PetscMemcpy(aij->i,mxGetJc(mmat),(mat->rmap.n+1)*sizeof(int));CHKERRQ(ierr);
62 
63   for (ii=0; ii<mat->rmap.n; ii++) {
64     aij->ilen[ii] = aij->imax[ii] = aij->i[ii+1] - aij->i[ii];
65   }
66 
67   ierr = MatAssemblyBegin(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
68   ierr = MatAssemblyEnd(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
69 
70   PetscFunctionReturn(0);
71 }
72 EXTERN_C_END
73 
74 #undef __FUNCT__
75 #define __FUNCT__ "MatSolve_Matlab"
76 PetscErrorCode MatSolve_Matlab(Mat A,Vec b,Vec x)
77 {
78   PetscErrorCode ierr;
79   const char     *_A,*_b,*_x;
80 
81   PetscFunctionBegin;
82   /* make sure objects have names; use default if not */
83   ierr = PetscObjectName((PetscObject)b);CHKERRQ(ierr);
84   ierr = PetscObjectName((PetscObject)x);CHKERRQ(ierr);
85 
86   ierr = PetscObjectGetName((PetscObject)A,&_A);CHKERRQ(ierr);
87   ierr = PetscObjectGetName((PetscObject)b,&_b);CHKERRQ(ierr);
88   ierr = PetscObjectGetName((PetscObject)x,&_x);CHKERRQ(ierr);
89   ierr = PetscMatlabEnginePut(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),(PetscObject)b);CHKERRQ(ierr);
90   ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),"%s = u%s\\(l%s\\(p%s*%s));",_x,_A,_A,_A,_b);CHKERRQ(ierr);
91   ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),"%s = 0;",_b);CHKERRQ(ierr);
92   /* ierr = PetscMatlabEnginePrintOutput(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),stdout);CHKERRQ(ierr);  */
93   ierr = PetscMatlabEngineGet(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),(PetscObject)x);CHKERRQ(ierr);
94   PetscFunctionReturn(0);
95 }
96 
97 #undef __FUNCT__
98 #define __FUNCT__ "MatLUFactorNumeric_Matlab"
99 PetscErrorCode MatLUFactorNumeric_Matlab(Mat A,MatFactorInfo *info,Mat *F)
100 {
101   PetscErrorCode ierr;
102   size_t         len;
103   char           *_A,*name;
104 
105   PetscFunctionBegin;
106   ierr = PetscMatlabEnginePut(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),(PetscObject)A);CHKERRQ(ierr);
107   _A   = A->name;
108   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);
109   ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),"%s = 0;",_A);CHKERRQ(ierr);
110   ierr = PetscStrlen(_A,&len);CHKERRQ(ierr);
111   ierr = PetscMalloc((len+2)*sizeof(char),&name);CHKERRQ(ierr);
112   sprintf(name,"_%s",_A);
113   ierr = PetscObjectSetName((PetscObject)*F,name);CHKERRQ(ierr);
114   ierr = PetscFree(name);CHKERRQ(ierr);
115   PetscFunctionReturn(0);
116 }
117 
118 #undef __FUNCT__
119 #define __FUNCT__ "MatLUFactorSymbolic_Matlab"
120 PetscErrorCode MatLUFactorSymbolic_Matlab(Mat A,IS r,IS c,MatFactorInfo *info,Mat *F)
121 {
122   PetscErrorCode ierr;
123 
124   PetscFunctionBegin;
125   if (A->cmap.N != A->rmap.N) SETERRQ(PETSC_ERR_ARG_SIZ,"matrix must be square");
126   ierr                       = MatCreate(((PetscObject)A)->comm,F);CHKERRQ(ierr);
127   ierr                       = MatSetSizes(*F,A->rmap.n,A->cmap.n,A->rmap.n,A->cmap.n);CHKERRQ(ierr);
128   ierr                       = MatSetType(*F,((PetscObject)A)->type_name);CHKERRQ(ierr);
129   ierr                       = MatSeqAIJSetPreallocation(*F,0,PETSC_NULL);CHKERRQ(ierr);
130   (*F)->ops->solve           = MatSolve_Matlab;
131   (*F)->ops->lufactornumeric = MatLUFactorNumeric_Matlab;
132   (*F)->factor               = MAT_FACTOR_LU;
133   PetscFunctionReturn(0);
134 }
135 
136 #undef __FUNCT__
137 #define __FUNCT__ "MatGetFactor_seqaij_matlab"
138 PetscErrorCode MatGetFactor_seqaij_matlab(Mat A,MatFactorType ftype,Mat *F)
139 {
140   PetscErrorCode ierr;
141 
142   PetscFunctionBegin;
143   if (A->cmap.N != A->rmap.N) SETERRQ(PETSC_ERR_ARG_SIZ,"matrix must be square");
144   ierr                        = MatCreate(((PetscObject)A)->comm,F);CHKERRQ(ierr);
145   ierr                        = MatSetSizes(*F,A->rmap.n,A->cmap.n,A->rmap.n,A->cmap.n);CHKERRQ(ierr);
146   ierr                        = MatSetType(*F,((PetscObject)A)->type_name);CHKERRQ(ierr);
147   ierr                        = MatSeqAIJSetPreallocation(*F,0,PETSC_NULL);CHKERRQ(ierr);
148   (*F)->ops->solve            = MatSolve_Matlab;
149   (*F)->ops->lufactornumeric  = MatLUFactorNumeric_Matlab;
150   (*F)->ops->lufactorsymbolic = MatLUFactorSymbolic_Matlab;
151   (*F)->factor                = MAT_FACTOR_LU;
152   PetscFunctionReturn(0);
153 }
154 
155 
156 /* --------------------------------------------------------------------------------*/
157 #undef __FUNCT__
158 #define __FUNCT__ "MatILUDTFactor_Matlab"
159 PetscErrorCode MatILUDTFactor_Matlab(Mat A,IS isrow,IS iscol,MatFactorInfo *info,Mat *F)
160 {
161   PetscErrorCode ierr;
162   size_t         len;
163   char           *_A,*name;
164 
165   PetscFunctionBegin;
166   if (info->dt == PETSC_DEFAULT)      info->dt      = .005;
167   if (info->dtcol == PETSC_DEFAULT)   info->dtcol   = .01;
168   if (A->cmap.N != A->rmap.N) SETERRQ(PETSC_ERR_ARG_SIZ,"matrix must be square");
169   ierr                       = MatCreate(((PetscObject)A)->comm,F);CHKERRQ(ierr);
170   ierr                       = MatSetSizes(*F,A->rmap.n,A->cmap.n,A->rmap.n,A->cmap.n);CHKERRQ(ierr);
171   ierr                       = MatSetType(*F,((PetscObject)A)->type_name);CHKERRQ(ierr);
172   ierr                       = MatSeqAIJSetPreallocation(*F,0,PETSC_NULL);CHKERRQ(ierr);
173   (*F)->ops->solve           = MatSolve_Matlab;
174   (*F)->factor               = MAT_FACTOR_LU;
175   ierr = PetscMatlabEnginePut(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),(PetscObject)A);CHKERRQ(ierr);
176   _A   = A->name;
177   ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),"info_%s = struct('droptol',%g,'thresh',%g);",_A,info->dt,info->dtcol);CHKERRQ(ierr);
178   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);
179   ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),"%s = 0;",_A);CHKERRQ(ierr);
180 
181   ierr = PetscStrlen(_A,&len);CHKERRQ(ierr);
182   ierr = PetscMalloc((len+2)*sizeof(char),&name);CHKERRQ(ierr);
183   sprintf(name,"_%s",_A);
184   ierr = PetscObjectSetName((PetscObject)*F,name);CHKERRQ(ierr);
185   ierr = PetscFree(name);CHKERRQ(ierr);
186   PetscFunctionReturn(0);
187 }
188 
189 #undef __FUNCT__
190 #define __FUNCT__ "MatFactorInfo_Matlab"
191 PetscErrorCode MatFactorInfo_Matlab(Mat A,PetscViewer viewer)
192 {
193   PetscErrorCode ierr;
194 
195   PetscFunctionBegin;
196   ierr = PetscViewerASCIIPrintf(viewer,"Matlab run parameters:  -- not written yet!\n");CHKERRQ(ierr);
197   PetscFunctionReturn(0);
198 }
199 
200 #undef __FUNCT__
201 #define __FUNCT__ "MatView_Matlab"
202 PetscErrorCode MatView_Matlab(Mat A,PetscViewer viewer)
203 {
204   PetscErrorCode    ierr;
205   PetscTruth        iascii;
206   PetscViewerFormat format;
207   Mat_Matlab        *lu=(Mat_Matlab*)(A->spptr);
208 
209   PetscFunctionBegin;
210   ierr = MatView_SeqAIJ(A,viewer);CHKERRQ(ierr);
211   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);CHKERRQ(ierr);
212   if (iascii) {
213     ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
214     if (format == PETSC_VIEWER_ASCII_FACTOR_INFO) {
215       ierr = MatFactorInfo_Matlab(A,viewer);
216     }
217   }
218   PetscFunctionReturn(0);
219 }
220 
221 
222 /*MC
223   MATMATLAB - MATMATLAB = "matlab" - A matrix type providing direct solvers (LU and QR) and drop tolerance
224   based ILU factorization (ILUDT) for sequential matrices via the external package Matlab.
225 
226   If Matlab is instaled (see the manual for
227   instructions on how to declare the existence of external packages),
228   a matrix type can be constructed which invokes Matlab solvers.
229   After calling MatCreate(...,A), simply call MatSetType(A,MATMATLAB).
230   This matrix type is only supported for double precision real.
231 
232   This matrix inherits from MATSEQAIJ.  As a result, MatSeqAIJSetPreallocation is
233   supported for this matrix type.  One can also call MatConvert for an inplace conversion to or from
234   the MATSEQAIJ type without data copy.
235 
236   Options Database Keys:
237 + -mat_type matlab - sets the matrix type to "matlab" during a call to MatSetFromOptions()
238 - -mat_matlab_qr   - sets the direct solver to be QR instead of LU
239 
240   Level: beginner
241 
242 .seealso: PCLU
243 M*/
244 
245