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