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