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*/