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  MatlabEnginePut_SeqAIJ(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  MatlabEngineGet_SeqAIJ(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;
105:   PetscReal      dtcol = info->dtcol;

108:   if (F->factor == MAT_FACTOR_ILU || info->dt > 0) {
109:     if (info->dtcol == PETSC_DEFAULT)  dtcol = .01;
110:     F->ops->solve           = MatSolve_Matlab;
111:     F->factor               = MAT_FACTOR_LU;
112:     PetscMatlabEnginePut(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),(PetscObject)A);
113:     _A   = ((PetscObject)A)->name;
114:     PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),"info_%s = struct('droptol',%g,'thresh',%g);",_A,info->dt,dtcol);
115:     PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),"[l_%s,u_%s,p_%s] = luinc(%s',info_%s);",_A,_A,_A,_A,_A);
116:     PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),"%s = 0;",_A);

118:     PetscStrlen(_A,&len);
119:     PetscMalloc((len+2)*sizeof(char),&name);
120:     sprintf(name,"_%s",_A);
121:     PetscObjectSetName((PetscObject)F,name);
122:     PetscFree(name);
123:   } else {
124:     PetscMatlabEnginePut(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),(PetscObject)A);
125:     _A   = ((PetscObject)A)->name;
126:     PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),"[l_%s,u_%s,p_%s] = lu(%s',%g);",_A,_A,_A,_A,dtcol);
127:     PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(((PetscObject)A)->comm),"%s = 0;",_A);
128:     PetscStrlen(_A,&len);
129:     PetscMalloc((len+2)*sizeof(char),&name);
130:     sprintf(name,"_%s",_A);
131:     PetscObjectSetName((PetscObject)F,name);
132:     PetscFree(name);
133:     F->ops->solve              = MatSolve_Matlab;
134:   }
135:   return(0);
136: }

140: PetscErrorCode MatLUFactorSymbolic_Matlab(Mat F,Mat A,IS r,IS c,const MatFactorInfo *info)
141: {
143:   if (A->cmap->N != A->rmap->N) SETERRQ(PETSC_ERR_ARG_SIZ,"matrix must be square");
144:   F->ops->lufactornumeric    = MatLUFactorNumeric_Matlab;
145:   F->assembled = PETSC_TRUE;
146:   return(0);
147: }

152: PetscErrorCode MatFactorGetSolverPackage_seqaij_matlab(Mat A,const MatSolverPackage *type)
153: {
155:   *type = MAT_SOLVER_MATLAB;
156:   return(0);
157: }

162: PetscErrorCode MatGetFactor_seqaij_matlab(Mat A,MatFactorType ftype,Mat *F)
163: {

167:   if (A->cmap->N != A->rmap->N) SETERRQ(PETSC_ERR_ARG_SIZ,"matrix must be square");
168:   MatCreate(((PetscObject)A)->comm,F);
169:   MatSetSizes(*F,A->rmap->n,A->cmap->n,A->rmap->n,A->cmap->n);
170:   MatSetType(*F,((PetscObject)A)->type_name);
171:   MatSeqAIJSetPreallocation(*F,0,PETSC_NULL);
172:   (*F)->ops->lufactorsymbolic  = MatLUFactorSymbolic_Matlab;
173:   (*F)->ops->ilufactorsymbolic = MatLUFactorSymbolic_Matlab;
174:   PetscObjectComposeFunctionDynamic((PetscObject)(*F),"MatFactorGetSolverPackage_C","MatFactorGetSolverPackage_seqaij_matlab",MatFactorGetSolverPackage_seqaij_matlab);

176:   (*F)->factor                = ftype;
177:   return(0);
178: }


181: /* --------------------------------------------------------------------------------*/

185: PetscErrorCode MatFactorInfo_Matlab(Mat A,PetscViewer viewer)
186: {
188: 
190:   PetscViewerASCIIPrintf(viewer,"Matlab run parameters:  -- not written yet!\n");
191:   return(0);
192: }

196: PetscErrorCode MatView_Matlab(Mat A,PetscViewer viewer)
197: {
198:   PetscErrorCode    ierr;
199:   PetscTruth        iascii;
200:   PetscViewerFormat format;

203:   MatView_SeqAIJ(A,viewer);
204:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);
205:   if (iascii) {
206:     PetscViewerGetFormat(viewer,&format);
207:     if (format == PETSC_VIEWER_ASCII_FACTOR_INFO) {
208:       MatFactorInfo_Matlab(A,viewer);
209:     }
210:   }
211:   return(0);
212: }


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


220:   Works with MATSEQAIJ matrices.

222:   Options Database Keys:
223: . -pc_factor_mat_solver_type matlab - selects Matlab to do the sparse factorization


226:   Level: beginner

228: .seealso: PCLU

230: .seealso: PCFactorSetMatSolverPackage(), MatSolverPackage
231: M*/