Actual source code: aijmatlab.c

  1: #define PETSCMAT_DLL

  3: /* 
  4:         Provides an interface for the Matlab engine sparse solver

  6: */
 7:  #include ../src/mat/impls/aij/seq/aij.h

  9: #include "engine.h"   /* Matlab include file */
 10: #include "mex.h"      /* Matlab include file */


 16: PetscErrorCode  MatMatlabEnginePut_Matlab(PetscObject obj,void *mengine)
 17: {
 19:   Mat            B = (Mat)obj;
 20:   mxArray        *mat;
 21:   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*)B->data;

 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:   PetscMemcpy(mxGetPr(mat),aij->a,aij->nz*sizeof(PetscScalar));
 27:   /* Matlab stores by column, not row so we pass in the transpose of the matrix */
 28:   PetscMemcpy(mxGetIr(mat),aij->j,aij->nz*sizeof(int));
 29:   PetscMemcpy(mxGetJc(mat),aij->i,(B->rmap->n+1)*sizeof(int));

 31:   /* Matlab indices start at 0 for sparse (what a surprise) */
 32: 
 33:   PetscObjectName(obj);
 34:   engPutVariable((Engine *)mengine,obj->name,mat);
 35:   return(0);
 36: }

 42: PetscErrorCode  MatMatlabEngineGet_Matlab(PetscObject obj,void *mengine)
 43: {
 45:   int            ii;
 46:   Mat            mat = (Mat)obj;
 47:   Mat_SeqAIJ     *aij = (Mat_SeqAIJ*)mat->data;
 48:   mxArray        *mmat;

 51:   MatSeqXAIJFreeAIJ(mat,&aij->a,&aij->j,&aij->i);

 53:   mmat = engGetVariable((Engine *)mengine,obj->name);

 55:   aij->nz           = (mxGetJc(mmat))[mat->rmap->n];
 56:   PetscMalloc3(aij->nz,PetscScalar,&aij->a,aij->nz,PetscInt,&aij->j,mat->rmap->n+1,PetscInt,&aij->i);
 57:   aij->singlemalloc = PETSC_TRUE;

 59:   PetscMemcpy(aij->a,mxGetPr(mmat),aij->nz*sizeof(PetscScalar));
 60:   /* Matlab stores by column, not row so we pass in the transpose of the matrix */
 61:   PetscMemcpy(aij->j,mxGetIr(mmat),aij->nz*sizeof(int));
 62:   PetscMemcpy(aij->i,mxGetJc(mmat),(mat->rmap->n+1)*sizeof(int));

 64:   for (ii=0; ii<mat->rmap->n; ii++) {
 65:     aij->ilen[ii] = aij->imax[ii] = aij->i[ii+1] - aij->i[ii];
 66:   }

 68:   MatAssemblyBegin(mat,MAT_FINAL_ASSEMBLY);
 69:   MatAssemblyEnd(mat,MAT_FINAL_ASSEMBLY);

 71:   return(0);
 72: }

 77: PetscErrorCode MatSolve_Matlab(Mat A,Vec b,Vec x)
 78: {
 80:   const char     *_A,*_b,*_x;

 83:   /* make sure objects have names; use default if not */
 84:   PetscObjectName((PetscObject)b);
 85:   PetscObjectName((PetscObject)x);

 87:   PetscObjectGetName((PetscObject)A,&_A);
 88:   PetscObjectGetName((PetscObject)b,&_b);
 89:   PetscObjectGetName((PetscObject)x,&_x);
 90:   PetscMatlabEnginePut(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),(PetscObject)b);
 91:   PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),"%s = u%s\\(l%s\\(p%s*%s));",_x,_A,_A,_A,_b);
 92:   PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),"%s = 0;",_b);
 93:   /* PetscMatlabEnginePrintOutput(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),stdout);  */
 94:   PetscMatlabEngineGet(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),(PetscObject)x);
 95:   return(0);
 96: }

100: PetscErrorCode MatLUFactorNumeric_Matlab(Mat F,Mat A,const MatFactorInfo *info)
101: {
103:   size_t         len;
104:   char           *_A,*name;

107:   PetscMatlabEnginePut(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),(PetscObject)A);
108:   _A   = ((PetscObject)A)->name;
109:   PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),"[l_%s,u_%s,p_%s] = lu(%s',%g);",_A,_A,_A,_A,info->dtcol);
110:   PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),"%s = 0;",_A);
111:   PetscStrlen(_A,&len);
112:   PetscMalloc((len+2)*sizeof(char),&name);
113:   sprintf(name,"_%s",_A);
114:   PetscObjectSetName((PetscObject)F,name);
115:   PetscFree(name);
116:   F->ops->solve              = MatSolve_Matlab;
117:   return(0);
118: }

122: PetscErrorCode MatLUFactorSymbolic_Matlab(Mat F,Mat A,IS r,IS c,const MatFactorInfo *info)
123: {
125:   if (A->cmap->N != A->rmap->N) SETERRQ(PETSC_ERR_ARG_SIZ,"matrix must be square");
126:   F->ops->lufactornumeric    = MatLUFactorNumeric_Matlab;
127:   return(0);
128: }

133: PetscErrorCode MatFactorGetSolverPackage_seqaij_matlab(Mat A,const MatSolverPackage *type)
134: {
136:   *type = MAT_SOLVER_MATLAB;
137:   return(0);
138: }

143: PetscErrorCode MatGetFactor_seqaij_matlab(Mat A,MatFactorType ftype,Mat *F)
144: {

148:   if (A->cmap->N != A->rmap->N) SETERRQ(PETSC_ERR_ARG_SIZ,"matrix must be square");
149:   MatCreate(((PetscObject)A)->comm,F);
150:   MatSetSizes(*F,A->rmap->n,A->cmap->n,A->rmap->n,A->cmap->n);
151:   MatSetType(*F,((PetscObject)A)->type_name);
152:   MatSeqAIJSetPreallocation(*F,0,PETSC_NULL);
153:   (*F)->ops->lufactorsymbolic = MatLUFactorSymbolic_Matlab;
154:   PetscObjectComposeFunctionDynamic((PetscObject)B,"MatFactorGetSolverPackage_C","MatFactorGetSolverPackage_seqaij_matlab",MatFactorGetSolverPackage_seqaij_matlab);

156:   (*F)->factor                = MAT_FACTOR_LU;
157:   return(0);
158: }


161: /* --------------------------------------------------------------------------------*/
164: PetscErrorCode MatILUDTFactor_Matlab(Mat A,IS isrow,IS iscol,const MatFactorInfo *info)
165: {
167:   size_t         len;
168:   char           *_A,*name;
169:   PetscReal      dt,dtcol;
170:   Mat            F;

173:   if (info->dt == PETSC_DEFAULT)      dt    = .005;
174:   if (info->dtcol == PETSC_DEFAULT)   dtcol = .01;
175:   MatGetFactor(A,MAT_SOLVER_MATLAB,MAT_FACTOR_ILU,&F);
176:   F->ops->solve           = MatSolve_Matlab;
177:   F->factor               = MAT_FACTOR_LU;
178:   PetscMatlabEnginePut(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),(PetscObject)A);
179:   _A   = ((PetscObject)A)->name;
180:   PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),"info_%s = struct('droptol',%g,'thresh',%g);",_A,dt,dtcol);
181:   PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),"[l_%s,u_%s,p_%s] = luinc(%s',info_%s);",_A,_A,_A,_A,_A);
182:   PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),"%s = 0;",_A);

184:   PetscStrlen(_A,&len);
185:   PetscMalloc((len+2)*sizeof(char),&name);
186:   sprintf(name,"_%s",_A);
187:   PetscObjectSetName((PetscObject)F,name);
188:   PetscFree(name);
189:   return(0);
190: }

194: PetscErrorCode MatFactorInfo_Matlab(Mat A,PetscViewer viewer)
195: {
197: 
199:   PetscViewerASCIIPrintf(viewer,"Matlab run parameters:  -- not written yet!\n");
200:   return(0);
201: }

205: PetscErrorCode MatView_Matlab(Mat A,PetscViewer viewer)
206: {
207:   PetscErrorCode    ierr;
208:   PetscTruth        iascii;
209:   PetscViewerFormat format;

212:   MatView_SeqAIJ(A,viewer);
213:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);
214:   if (iascii) {
215:     PetscViewerGetFormat(viewer,&format);
216:     if (format == PETSC_VIEWER_ASCII_FACTOR_INFO) {
217:       MatFactorInfo_Matlab(A,viewer);
218:     }
219:   }
220:   return(0);
221: }


224: /*MC
225:   MAT_SOLVER_MATLAB - "matlab" - Providing direct solvers (LU and QR) and drop tolerance
226:   based ILU factorization (ILUDT) for sequential matrices via the external package Matlab.


229:   Works with MATSEQAIJ matrices.

231:   Options Database Keys:
232: . -pc_factor_mat_solver_type matlab - selects Matlab to do the sparse factorization


235:   Level: beginner

237: .seealso: PCLU

239: .seealso: PCFactorSetMatSolverPackage(), MatSolverPackage
240: M*/