xref: /petsc/src/mat/impls/aij/seq/matlab/aijmatlab.c (revision be1d678a52e6eff2808b2fa31ae986cdbf03c9fe)
1*be1d678aSKris Buschelman #define PETSCMAT_DLL
2*be1d678aSKris Buschelman 
33b3e256bSKris Buschelman /*
43b3e256bSKris Buschelman         Provides an interface for the Matlab engine sparse solver
53b3e256bSKris Buschelman 
63b3e256bSKris Buschelman */
73b3e256bSKris Buschelman #include "src/mat/impls/aij/seq/aij.h"
83b3e256bSKris Buschelman 
93b3e256bSKris Buschelman #include "engine.h"   /* Matlab include file */
103b3e256bSKris Buschelman #include "mex.h"      /* Matlab include file */
113b3e256bSKris Buschelman 
1205db81ecSKris Buschelman typedef struct {
136849ba73SBarry Smith   PetscErrorCode (*MatDuplicate)(Mat,MatDuplicateOption,Mat*);
146849ba73SBarry Smith   PetscErrorCode (*MatView)(Mat,PetscViewer);
156849ba73SBarry Smith   PetscErrorCode (*MatLUFactorSymbolic)(Mat,IS,IS,MatFactorInfo*,Mat*);
167529efd4SKris Buschelman   PetscErrorCode (*MatILUDTFactor)(Mat,IS,IS,MatFactorInfo*,Mat*);
176849ba73SBarry Smith   PetscErrorCode (*MatDestroy)(Mat);
1805db81ecSKris Buschelman } Mat_Matlab;
1905db81ecSKris Buschelman 
20a1d52234SKris Buschelman 
21a1d52234SKris Buschelman EXTERN_C_BEGIN
22a1d52234SKris Buschelman #undef __FUNCT__
23a1d52234SKris Buschelman #define __FUNCT__ "MatMatlabEnginePut_Matlab"
24*be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatMatlabEnginePut_Matlab(PetscObject obj,void *mengine)
25a1d52234SKris Buschelman {
26dfbe8321SBarry Smith   PetscErrorCode ierr;
27a1d52234SKris Buschelman   Mat         B = (Mat)obj;
28a1d52234SKris Buschelman   mxArray     *mat;
29a1d52234SKris Buschelman   Mat_SeqAIJ  *aij = (Mat_SeqAIJ*)B->data;
30a1d52234SKris Buschelman 
31a1d52234SKris Buschelman   PetscFunctionBegin;
32a1d52234SKris Buschelman   mat  = mxCreateSparse(B->n,B->m,aij->nz,mxREAL);
33a1d52234SKris Buschelman   ierr = PetscMemcpy(mxGetPr(mat),aij->a,aij->nz*sizeof(PetscScalar));CHKERRQ(ierr);
34a1d52234SKris Buschelman   /* Matlab stores by column, not row so we pass in the transpose of the matrix */
35a1d52234SKris Buschelman   ierr = PetscMemcpy(mxGetIr(mat),aij->j,aij->nz*sizeof(int));CHKERRQ(ierr);
36a1d52234SKris Buschelman   ierr = PetscMemcpy(mxGetJc(mat),aij->i,(B->m+1)*sizeof(int));CHKERRQ(ierr);
37a1d52234SKris Buschelman 
38a1d52234SKris Buschelman   /* Matlab indices start at 0 for sparse (what a surprise) */
39a1d52234SKris Buschelman 
40a1d52234SKris Buschelman   ierr = PetscObjectName(obj);CHKERRQ(ierr);
41a1d52234SKris Buschelman   engPutVariable((Engine *)mengine,obj->name,mat);
42a1d52234SKris Buschelman   PetscFunctionReturn(0);
43a1d52234SKris Buschelman }
44a1d52234SKris Buschelman EXTERN_C_END
45a1d52234SKris Buschelman 
46a1d52234SKris Buschelman EXTERN_C_BEGIN
47a1d52234SKris Buschelman #undef __FUNCT__
48a1d52234SKris Buschelman #define __FUNCT__ "MatMatlabEngineGet_Matlab"
49*be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatMatlabEngineGet_Matlab(PetscObject obj,void *mengine)
50a1d52234SKris Buschelman {
51dfbe8321SBarry Smith   PetscErrorCode ierr;
52dfbe8321SBarry Smith   int        ii;
53a1d52234SKris Buschelman   Mat        mat = (Mat)obj;
54a1d52234SKris Buschelman   Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data;
55a1d52234SKris Buschelman   mxArray    *mmat;
56a1d52234SKris Buschelman 
57a1d52234SKris Buschelman   PetscFunctionBegin;
58a1d52234SKris Buschelman   ierr = PetscFree(aij->a);CHKERRQ(ierr);
59a1d52234SKris Buschelman 
60a1d52234SKris Buschelman   mmat = engGetVariable((Engine *)mengine,obj->name);
61a1d52234SKris Buschelman 
62a1d52234SKris Buschelman   aij->nz           = (mxGetJc(mmat))[mat->m];
63a1d52234SKris Buschelman   ierr              = PetscMalloc(((size_t) aij->nz)*(sizeof(int)+sizeof(PetscScalar))+(mat->m+1)*sizeof(int),&aij->a);CHKERRQ(ierr);
64a1d52234SKris Buschelman   aij->j            = (int*)(aij->a + aij->nz);
65a1d52234SKris Buschelman   aij->i            = aij->j + aij->nz;
66a1d52234SKris Buschelman   aij->singlemalloc = PETSC_TRUE;
67a1d52234SKris Buschelman   aij->freedata     = PETSC_TRUE;
68a1d52234SKris Buschelman 
69a1d52234SKris Buschelman   ierr = PetscMemcpy(aij->a,mxGetPr(mmat),aij->nz*sizeof(PetscScalar));CHKERRQ(ierr);
70a1d52234SKris Buschelman   /* Matlab stores by column, not row so we pass in the transpose of the matrix */
71a1d52234SKris Buschelman   ierr = PetscMemcpy(aij->j,mxGetIr(mmat),aij->nz*sizeof(int));CHKERRQ(ierr);
72a1d52234SKris Buschelman   ierr = PetscMemcpy(aij->i,mxGetJc(mmat),(mat->m+1)*sizeof(int));CHKERRQ(ierr);
73a1d52234SKris Buschelman 
74a1d52234SKris Buschelman   for (ii=0; ii<mat->m; ii++) {
75a1d52234SKris Buschelman     aij->ilen[ii] = aij->imax[ii] = aij->i[ii+1] - aij->i[ii];
76a1d52234SKris Buschelman   }
77a1d52234SKris Buschelman 
78a1d52234SKris Buschelman   ierr = MatAssemblyBegin(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
79a1d52234SKris Buschelman   ierr = MatAssemblyEnd(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
80a1d52234SKris Buschelman 
81a1d52234SKris Buschelman   PetscFunctionReturn(0);
82a1d52234SKris Buschelman }
83a1d52234SKris Buschelman EXTERN_C_END
84a1d52234SKris Buschelman 
8505db81ecSKris Buschelman EXTERN_C_BEGIN
863b3e256bSKris Buschelman #undef __FUNCT__
8705db81ecSKris Buschelman #define __FUNCT__ "MatConvert_Matlab_SeqAIJ"
88*be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatConvert_Matlab_SeqAIJ(Mat A,const MatType type,MatReuse reuse,Mat *newmat)
89521d7252SBarry Smith {
90dfbe8321SBarry Smith   PetscErrorCode ierr;
9105db81ecSKris Buschelman   Mat            B=*newmat;
9205db81ecSKris Buschelman   Mat_Matlab    *lu=(Mat_Matlab*)A->spptr;
9305db81ecSKris Buschelman 
9405db81ecSKris Buschelman   PetscFunctionBegin;
95ceb03754SKris Buschelman   if (reuse == MAT_INITIAL_MATRIX) {
9605db81ecSKris Buschelman     ierr = MatDuplicate(A,MAT_COPY_VALUES,&B);CHKERRQ(ierr);
9705db81ecSKris Buschelman   }
98901853e0SKris Buschelman   B->ops->duplicate        = lu->MatDuplicate;
99901853e0SKris Buschelman   B->ops->view             = lu->MatView;
100901853e0SKris Buschelman   B->ops->lufactorsymbolic = lu->MatLUFactorSymbolic;
101901853e0SKris Buschelman   B->ops->iludtfactor      = lu->MatILUDTFactor;
102901853e0SKris Buschelman   B->ops->destroy          = lu->MatDestroy;
10305db81ecSKris Buschelman 
10405db81ecSKris Buschelman   ierr = PetscFree(lu);CHKERRQ(ierr);
105901853e0SKris Buschelman 
106901853e0SKris Buschelman   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_matlab_C","",PETSC_NULL);CHKERRQ(ierr);
107901853e0SKris Buschelman   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_matlab_seqaij_C","",PETSC_NULL);CHKERRQ(ierr);
108901853e0SKris Buschelman   ierr = PetscObjectComposeFunction((PetscObject)B,"PetscMatlabEnginePut_C","",PETSC_NULL);CHKERRQ(ierr);
109901853e0SKris Buschelman   ierr = PetscObjectComposeFunction((PetscObject)B,"PetscMatlabEngineGet_C","",PETSC_NULL);CHKERRQ(ierr);
110901853e0SKris Buschelman 
11105db81ecSKris Buschelman   ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr);
11205db81ecSKris Buschelman   *newmat = B;
11305db81ecSKris Buschelman   PetscFunctionReturn(0);
11405db81ecSKris Buschelman }
11505db81ecSKris Buschelman EXTERN_C_END
11605db81ecSKris Buschelman 
11705db81ecSKris Buschelman #undef __FUNCT__
11805db81ecSKris Buschelman #define __FUNCT__ "MatDestroy_Matlab"
119dfbe8321SBarry Smith PetscErrorCode MatDestroy_Matlab(Mat A)
120dfbe8321SBarry Smith {
121dfbe8321SBarry Smith   PetscErrorCode ierr;
12205db81ecSKris Buschelman 
12305db81ecSKris Buschelman   PetscFunctionBegin;
12405db81ecSKris Buschelman   ierr = MatConvert_Matlab_SeqAIJ(A,MATSEQAIJ,&A);CHKERRQ(ierr);
12505db81ecSKris Buschelman   ierr = (*A->ops->destroy)(A);CHKERRQ(ierr);
12605db81ecSKris Buschelman   PetscFunctionReturn(0);
12705db81ecSKris Buschelman }
12805db81ecSKris Buschelman 
12905db81ecSKris Buschelman #undef __FUNCT__
13005db81ecSKris Buschelman #define __FUNCT__ "MatSolve_Matlab"
131dfbe8321SBarry Smith PetscErrorCode MatSolve_Matlab(Mat A,Vec b,Vec x)
1323b3e256bSKris Buschelman {
133dfbe8321SBarry Smith   PetscErrorCode ierr;
1343b3e256bSKris Buschelman   char            *_A,*_b,*_x;
1353b3e256bSKris Buschelman 
1363b3e256bSKris Buschelman   PetscFunctionBegin;
1373b3e256bSKris Buschelman   /* make sure objects have names; use default if not */
1383b3e256bSKris Buschelman   ierr = PetscObjectName((PetscObject)b);CHKERRQ(ierr);
1393b3e256bSKris Buschelman   ierr = PetscObjectName((PetscObject)x);CHKERRQ(ierr);
1403b3e256bSKris Buschelman 
1413b3e256bSKris Buschelman   ierr = PetscObjectGetName((PetscObject)A,&_A);CHKERRQ(ierr);
1423b3e256bSKris Buschelman   ierr = PetscObjectGetName((PetscObject)b,&_b);CHKERRQ(ierr);
1433b3e256bSKris Buschelman   ierr = PetscObjectGetName((PetscObject)x,&_x);CHKERRQ(ierr);
1443b3e256bSKris Buschelman   ierr = PetscMatlabEnginePut(PETSC_MATLAB_ENGINE_(A->comm),(PetscObject)b);CHKERRQ(ierr);
1453b3e256bSKris Buschelman   ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(A->comm),"%s = u%s\\(l%s\\(p%s*%s));",_x,_A,_A,_A,_b);CHKERRQ(ierr);
1463b3e256bSKris Buschelman   ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(A->comm),"%s = 0;",_b);CHKERRQ(ierr);
1473b3e256bSKris Buschelman   /* ierr = PetscMatlabEnginePrintOutput(PETSC_MATLAB_ENGINE_(A->comm),stdout);CHKERRQ(ierr);  */
1483b3e256bSKris Buschelman   ierr = PetscMatlabEngineGet(PETSC_MATLAB_ENGINE_(A->comm),(PetscObject)x);CHKERRQ(ierr);
1493b3e256bSKris Buschelman   PetscFunctionReturn(0);
1503b3e256bSKris Buschelman }
1513b3e256bSKris Buschelman 
1523b3e256bSKris Buschelman #undef __FUNCT__
15305db81ecSKris Buschelman #define __FUNCT__ "MatLUFactorNumeric_Matlab"
154af281ebdSHong Zhang PetscErrorCode MatLUFactorNumeric_Matlab(Mat A,MatFactorInfo *info,Mat *F)
1553b3e256bSKris Buschelman {
1563b3e256bSKris Buschelman   Mat_SeqAIJ      *f = (Mat_SeqAIJ*)(*F)->data;
157dfbe8321SBarry Smith   PetscErrorCode ierr;
158de4209c5SBarry Smith   size_t          len;
1593b3e256bSKris Buschelman   char            *_A,*name;
1603b3e256bSKris Buschelman 
1613b3e256bSKris Buschelman   PetscFunctionBegin;
1623b3e256bSKris Buschelman   ierr = PetscMatlabEnginePut(PETSC_MATLAB_ENGINE_(A->comm),(PetscObject)A);CHKERRQ(ierr);
1633b3e256bSKris Buschelman   _A   = A->name;
1641d18e487SKris Buschelman   ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(A->comm),"[l_%s,u_%s,p_%s] = lu(%s',%g);",_A,_A,_A,_A,info->dtcol);CHKERRQ(ierr);
1653b3e256bSKris Buschelman   ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(A->comm),"%s = 0;",_A);CHKERRQ(ierr);
1663b3e256bSKris Buschelman   ierr = PetscStrlen(_A,&len);CHKERRQ(ierr);
1673b3e256bSKris Buschelman   ierr = PetscMalloc((len+2)*sizeof(char),&name);CHKERRQ(ierr);
1683b3e256bSKris Buschelman   sprintf(name,"_%s",_A);
1693b3e256bSKris Buschelman   ierr = PetscObjectSetName((PetscObject)*F,name);CHKERRQ(ierr);
1703b3e256bSKris Buschelman   ierr = PetscFree(name);CHKERRQ(ierr);
1713b3e256bSKris Buschelman   PetscFunctionReturn(0);
1723b3e256bSKris Buschelman }
1733b3e256bSKris Buschelman 
1743b3e256bSKris Buschelman #undef __FUNCT__
17505db81ecSKris Buschelman #define __FUNCT__ "MatLUFactorSymbolic_Matlab"
176dfbe8321SBarry Smith PetscErrorCode MatLUFactorSymbolic_Matlab(Mat A,IS r,IS c,MatFactorInfo *info,Mat *F)
1773b3e256bSKris Buschelman {
178dfbe8321SBarry Smith   PetscErrorCode ierr;
1793b3e256bSKris Buschelman   Mat_SeqAIJ *f;
1803b3e256bSKris Buschelman 
1813b3e256bSKris Buschelman   PetscFunctionBegin;
1823b3e256bSKris Buschelman   if (A->N != A->M) SETERRQ(PETSC_ERR_ARG_SIZ,"matrix must be square");
1833b3e256bSKris Buschelman   ierr                       = MatCreate(A->comm,A->m,A->n,A->m,A->n,F);CHKERRQ(ierr);
1843b3e256bSKris Buschelman   ierr                       = MatSetType(*F,A->type_name);CHKERRQ(ierr);
1853b3e256bSKris Buschelman   ierr                       = MatSeqAIJSetPreallocation(*F,0,PETSC_NULL);CHKERRQ(ierr);
18605db81ecSKris Buschelman   (*F)->ops->solve           = MatSolve_Matlab;
18705db81ecSKris Buschelman   (*F)->ops->lufactornumeric = MatLUFactorNumeric_Matlab;
1883b3e256bSKris Buschelman   (*F)->factor               = FACTOR_LU;
1893b3e256bSKris Buschelman   f                          = (Mat_SeqAIJ*)(*F)->data;
1903b3e256bSKris Buschelman   f->lu_dtcol = info->dtcol;
1913b3e256bSKris Buschelman   PetscFunctionReturn(0);
1923b3e256bSKris Buschelman }
1933b3e256bSKris Buschelman 
1943b3e256bSKris Buschelman /* ---------------------------------------------------------------------------------*/
1953b3e256bSKris Buschelman #undef __FUNCT__
19605db81ecSKris Buschelman #define __FUNCT__ "MatSolve_Matlab_QR"
197dfbe8321SBarry Smith PetscErrorCode MatSolve_Matlab_QR(Mat A,Vec b,Vec x)
1983b3e256bSKris Buschelman {
199dfbe8321SBarry Smith   PetscErrorCode ierr;
2003b3e256bSKris Buschelman   char            *_A,*_b,*_x;
2013b3e256bSKris Buschelman 
2023b3e256bSKris Buschelman   PetscFunctionBegin;
2033b3e256bSKris Buschelman   /* make sure objects have names; use default if not */
2043b3e256bSKris Buschelman   ierr = PetscObjectName((PetscObject)b);CHKERRQ(ierr);
2053b3e256bSKris Buschelman   ierr = PetscObjectName((PetscObject)x);CHKERRQ(ierr);
2063b3e256bSKris Buschelman 
2073b3e256bSKris Buschelman   ierr = PetscObjectGetName((PetscObject)A,&_A);CHKERRQ(ierr);
2083b3e256bSKris Buschelman   ierr = PetscObjectGetName((PetscObject)b,&_b);CHKERRQ(ierr);
2093b3e256bSKris Buschelman   ierr = PetscObjectGetName((PetscObject)x,&_x);CHKERRQ(ierr);
2103b3e256bSKris Buschelman   ierr = PetscMatlabEnginePut(PETSC_MATLAB_ENGINE_(A->comm),(PetscObject)b);CHKERRQ(ierr);
2113b3e256bSKris Buschelman   ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(A->comm),"%s = r%s\\(r%s'\\(%s*%s));",_x,_A,_A,_A+1,_b);CHKERRQ(ierr);
2123b3e256bSKris Buschelman   ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(A->comm),"%s = 0;",_b);CHKERRQ(ierr);
2133b3e256bSKris Buschelman   /* ierr = PetscMatlabEnginePrintOutput(PETSC_MATLAB_ENGINE_(A->comm),stdout);CHKERRQ(ierr);  */
2143b3e256bSKris Buschelman   ierr = PetscMatlabEngineGet(PETSC_MATLAB_ENGINE_(A->comm),(PetscObject)x);CHKERRQ(ierr);
2153b3e256bSKris Buschelman   PetscFunctionReturn(0);
2163b3e256bSKris Buschelman }
2173b3e256bSKris Buschelman 
2183b3e256bSKris Buschelman #undef __FUNCT__
21905db81ecSKris Buschelman #define __FUNCT__ "MatLUFactorNumeric_Matlab_QR"
220af281ebdSHong Zhang PetscErrorCode MatLUFactorNumeric_Matlab_QR(Mat A,MatFactorInfo *info,Mat *F)
2213b3e256bSKris Buschelman {
222dfbe8321SBarry Smith   PetscErrorCode ierr;
223de4209c5SBarry Smith   size_t          len;
2243b3e256bSKris Buschelman   char            *_A,*name;
2253b3e256bSKris Buschelman 
2263b3e256bSKris Buschelman   PetscFunctionBegin;
2273b3e256bSKris Buschelman   ierr = PetscMatlabEnginePut(PETSC_MATLAB_ENGINE_(A->comm),(PetscObject)A);CHKERRQ(ierr);
2283b3e256bSKris Buschelman   _A   = A->name;
2293b3e256bSKris Buschelman   ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(A->comm),"r_%s = qr(%s');",_A,_A);CHKERRQ(ierr);
2303b3e256bSKris Buschelman   ierr = PetscStrlen(_A,&len);CHKERRQ(ierr);
2313b3e256bSKris Buschelman   ierr = PetscMalloc((len+2)*sizeof(char),&name);CHKERRQ(ierr);
2323b3e256bSKris Buschelman   sprintf(name,"_%s",_A);
2333b3e256bSKris Buschelman   ierr = PetscObjectSetName((PetscObject)*F,name);CHKERRQ(ierr);
2343b3e256bSKris Buschelman   ierr = PetscFree(name);CHKERRQ(ierr);
2353b3e256bSKris Buschelman   PetscFunctionReturn(0);
2363b3e256bSKris Buschelman }
2373b3e256bSKris Buschelman 
2383b3e256bSKris Buschelman #undef __FUNCT__
23905db81ecSKris Buschelman #define __FUNCT__ "MatLUFactorSymbolic_Matlab_QR"
240dfbe8321SBarry Smith PetscErrorCode MatLUFactorSymbolic_Matlab_QR(Mat A,IS r,IS c,MatFactorInfo *info,Mat *F)
2413b3e256bSKris Buschelman {
242dfbe8321SBarry Smith   PetscErrorCode ierr;
2433b3e256bSKris Buschelman 
2443b3e256bSKris Buschelman   PetscFunctionBegin;
2453b3e256bSKris Buschelman   if (A->N != A->M) SETERRQ(PETSC_ERR_ARG_SIZ,"matrix must be square");
2463b3e256bSKris Buschelman   ierr                       = MatCreate(A->comm,A->m,A->n,A->m,A->n,F);CHKERRQ(ierr);
2473b3e256bSKris Buschelman   ierr                       = MatSetType(*F,A->type_name);CHKERRQ(ierr);
2483b3e256bSKris Buschelman   ierr                       = MatSeqAIJSetPreallocation(*F,0,PETSC_NULL);CHKERRQ(ierr);
24905db81ecSKris Buschelman   (*F)->ops->solve           = MatSolve_Matlab_QR;
25005db81ecSKris Buschelman   (*F)->ops->lufactornumeric = MatLUFactorNumeric_Matlab_QR;
2513b3e256bSKris Buschelman   (*F)->factor               = FACTOR_LU;
2523b3e256bSKris Buschelman   (*F)->assembled            = PETSC_TRUE;  /* required by -ksp_view */
2533b3e256bSKris Buschelman 
2543b3e256bSKris Buschelman   PetscFunctionReturn(0);
2553b3e256bSKris Buschelman }
2563b3e256bSKris Buschelman 
2573b3e256bSKris Buschelman /* --------------------------------------------------------------------------------*/
2583b3e256bSKris Buschelman #undef __FUNCT__
25905db81ecSKris Buschelman #define __FUNCT__ "MatILUDTFactor_Matlab"
2607529efd4SKris Buschelman PetscErrorCode MatILUDTFactor_Matlab(Mat A,IS isrow,IS iscol,MatFactorInfo *info,Mat *F)
2613b3e256bSKris Buschelman {
262dfbe8321SBarry Smith   PetscErrorCode ierr;
263de4209c5SBarry Smith   size_t     len;
2643b3e256bSKris Buschelman   char       *_A,*name;
2653b3e256bSKris Buschelman 
2663b3e256bSKris Buschelman   PetscFunctionBegin;
2673b3e256bSKris Buschelman   if (info->dt == PETSC_DEFAULT)      info->dt      = .005;
2683b3e256bSKris Buschelman   if (info->dtcol == PETSC_DEFAULT)   info->dtcol   = .01;
2693b3e256bSKris Buschelman   if (A->N != A->M) SETERRQ(PETSC_ERR_ARG_SIZ,"matrix must be square");
2703b3e256bSKris Buschelman   ierr                       = MatCreate(A->comm,A->m,A->n,A->m,A->n,F);CHKERRQ(ierr);
2713b3e256bSKris Buschelman   ierr                       = MatSetType(*F,A->type_name);CHKERRQ(ierr);
2723b3e256bSKris Buschelman   ierr                       = MatSeqAIJSetPreallocation(*F,0,PETSC_NULL);CHKERRQ(ierr);
273f365a357SKris Buschelman   (*F)->ops->solve           = MatSolve_Matlab;
2743b3e256bSKris Buschelman   (*F)->factor               = FACTOR_LU;
2753b3e256bSKris Buschelman   ierr = PetscMatlabEnginePut(PETSC_MATLAB_ENGINE_(A->comm),(PetscObject)A);CHKERRQ(ierr);
2763b3e256bSKris Buschelman   _A   = A->name;
2773b3e256bSKris Buschelman   ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(A->comm),"info_%s = struct('droptol',%g,'thresh',%g);",_A,info->dt,info->dtcol);CHKERRQ(ierr);
2783b3e256bSKris Buschelman   ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(A->comm),"[l_%s,u_%s,p_%s] = luinc(%s',info_%s);",_A,_A,_A,_A,_A);CHKERRQ(ierr);
2793b3e256bSKris Buschelman   ierr = PetscMatlabEngineEvaluate(PETSC_MATLAB_ENGINE_(A->comm),"%s = 0;",_A);CHKERRQ(ierr);
2803b3e256bSKris Buschelman 
2813b3e256bSKris Buschelman   ierr = PetscStrlen(_A,&len);CHKERRQ(ierr);
2823b3e256bSKris Buschelman   ierr = PetscMalloc((len+2)*sizeof(char),&name);CHKERRQ(ierr);
2833b3e256bSKris Buschelman   sprintf(name,"_%s",_A);
2843b3e256bSKris Buschelman   ierr = PetscObjectSetName((PetscObject)*F,name);CHKERRQ(ierr);
2853b3e256bSKris Buschelman   ierr = PetscFree(name);CHKERRQ(ierr);
2863b3e256bSKris Buschelman   PetscFunctionReturn(0);
2873b3e256bSKris Buschelman }
2883b3e256bSKris Buschelman 
28905db81ecSKris Buschelman #undef __FUNCT__
29005db81ecSKris Buschelman #define __FUNCT__ "MatFactorInfo_Matlab"
291dfbe8321SBarry Smith PetscErrorCode MatFactorInfo_Matlab(Mat A,PetscViewer viewer)
2923b3e256bSKris Buschelman {
293dfbe8321SBarry Smith   PetscErrorCode ierr;
2943b3e256bSKris Buschelman 
2953b3e256bSKris Buschelman   PetscFunctionBegin;
2963b3e256bSKris Buschelman   ierr = PetscViewerASCIIPrintf(viewer,"Matlab run parameters:  -- not written yet!\n");CHKERRQ(ierr);
2973b3e256bSKris Buschelman   PetscFunctionReturn(0);
2983b3e256bSKris Buschelman }
2993b3e256bSKris Buschelman 
3003b3e256bSKris Buschelman #undef __FUNCT__
30105db81ecSKris Buschelman #define __FUNCT__ "MatView_Matlab"
302dfbe8321SBarry Smith PetscErrorCode MatView_Matlab(Mat A,PetscViewer viewer) {
303dfbe8321SBarry Smith   PetscErrorCode    ierr;
30432077d6dSBarry Smith   PetscTruth        iascii;
30505db81ecSKris Buschelman   PetscViewerFormat format;
30605db81ecSKris Buschelman   Mat_Matlab        *lu=(Mat_Matlab*)(A->spptr);
30705db81ecSKris Buschelman 
30805db81ecSKris Buschelman   PetscFunctionBegin;
30905db81ecSKris Buschelman   ierr = (*lu->MatView)(A,viewer);CHKERRQ(ierr);
31032077d6dSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);CHKERRQ(ierr);
31132077d6dSBarry Smith   if (iascii) {
31205db81ecSKris Buschelman     ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
31305db81ecSKris Buschelman     if (format == PETSC_VIEWER_ASCII_FACTOR_INFO) {
31405db81ecSKris Buschelman       ierr = MatFactorInfo_Matlab(A,viewer);
31505db81ecSKris Buschelman     }
31605db81ecSKris Buschelman   }
31705db81ecSKris Buschelman   PetscFunctionReturn(0);
31805db81ecSKris Buschelman }
319f365a357SKris Buschelman 
320f365a357SKris Buschelman #undef __FUNCT__
321f365a357SKris Buschelman #define __FUNCT__ "MatDuplicate_Matlab"
322dfbe8321SBarry Smith PetscErrorCode MatDuplicate_Matlab(Mat A, MatDuplicateOption op, Mat *M) {
323dfbe8321SBarry Smith   PetscErrorCode ierr;
324f365a357SKris Buschelman   Mat_Matlab *lu=(Mat_Matlab*)A->spptr;
325f365a357SKris Buschelman 
326f365a357SKris Buschelman   PetscFunctionBegin;
327f365a357SKris Buschelman   ierr = (*lu->MatDuplicate)(A,op,M);CHKERRQ(ierr);
328f365a357SKris Buschelman   ierr = PetscMemcpy((*M)->spptr,lu,sizeof(Mat_Matlab));CHKERRQ(ierr);
329f365a357SKris Buschelman   PetscFunctionReturn(0);
330f365a357SKris Buschelman }
331f365a357SKris Buschelman 
332f365a357SKris Buschelman EXTERN_C_BEGIN
33305db81ecSKris Buschelman #undef __FUNCT__
33405db81ecSKris Buschelman #define __FUNCT__ "MatConvert_SeqAIJ_Matlab"
335*be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatConvert_SeqAIJ_Matlab(Mat A,const MatType type,MatReuse reuse,Mat *newmat)
336521d7252SBarry Smith {
33705db81ecSKris Buschelman   /* This routine is only called to convert to MATMATLAB */
33805db81ecSKris Buschelman   /* from MATSEQAIJ, so we will ignore 'MatType type'. */
339dfbe8321SBarry Smith   PetscErrorCode ierr;
34005db81ecSKris Buschelman   Mat            B=*newmat;
34105db81ecSKris Buschelman   Mat_Matlab     *lu;
3423b3e256bSKris Buschelman   PetscTruth     qr;
34305db81ecSKris Buschelman 
34405db81ecSKris Buschelman   PetscFunctionBegin;
345ceb03754SKris Buschelman   if (reuse == MAT_INITIAL_MATRIX) {
34605db81ecSKris Buschelman     ierr = MatDuplicate(A,MAT_COPY_VALUES,&B);CHKERRQ(ierr);
34705db81ecSKris Buschelman   }
34805db81ecSKris Buschelman 
34905db81ecSKris Buschelman   ierr = PetscNew(Mat_Matlab,&lu);CHKERRQ(ierr);
35005db81ecSKris Buschelman   lu->MatDuplicate         = A->ops->duplicate;
35105db81ecSKris Buschelman   lu->MatView              = A->ops->view;
35205db81ecSKris Buschelman   lu->MatLUFactorSymbolic  = A->ops->lufactorsymbolic;
35305db81ecSKris Buschelman   lu->MatILUDTFactor       = A->ops->iludtfactor;
35405db81ecSKris Buschelman   lu->MatDestroy           = A->ops->destroy;
35505db81ecSKris Buschelman 
35605db81ecSKris Buschelman   B->spptr                 = (void*)lu;
35705db81ecSKris Buschelman   B->ops->duplicate        = MatDuplicate_Matlab;
35805db81ecSKris Buschelman   B->ops->view             = MatView_Matlab;
35905db81ecSKris Buschelman   B->ops->lufactorsymbolic = MatLUFactorSymbolic_Matlab;
36005db81ecSKris Buschelman   B->ops->iludtfactor      = MatILUDTFactor_Matlab;
36105db81ecSKris Buschelman   B->ops->destroy          = MatDestroy_Matlab;
36205db81ecSKris Buschelman 
36305db81ecSKris Buschelman   ierr = PetscOptionsHasName(A->prefix,"-mat_matlab_qr",&qr);CHKERRQ(ierr);
36405db81ecSKris Buschelman   if (qr) {
36505db81ecSKris Buschelman     B->ops->lufactorsymbolic = MatLUFactorSymbolic_Matlab_QR;
36663ba0a88SBarry Smith     ierr = PetscLogInfo((0,"MatConvert_SeqAIJ_Matlab:Using Matlab QR with iterative refinement for LU factorization and solves\n"));CHKERRQ(ierr);
36705db81ecSKris Buschelman   } else {
36863ba0a88SBarry Smith     ierr = PetscLogInfo((0,"MatConvert_SeqAIJ_Matlab:Using Matlab for LU factorizations and solves.\n"));CHKERRQ(ierr);
36905db81ecSKris Buschelman   }
37063ba0a88SBarry Smith   ierr = PetscLogInfo((0,"MatConvert_SeqAIJ_Matlab:Using Matlab for ILUDT factorizations and solves.\n"));CHKERRQ(ierr);
37105db81ecSKris Buschelman 
37205db81ecSKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqaij_matlab_C",
37305db81ecSKris Buschelman                                            "MatConvert_SeqAIJ_Matlab",MatConvert_SeqAIJ_Matlab);CHKERRQ(ierr);
37405db81ecSKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_matlab_seqaij_C",
37505db81ecSKris Buschelman                                            "MatConvert_Matlab_SeqAIJ",MatConvert_Matlab_SeqAIJ);CHKERRQ(ierr);
376a1d52234SKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"PetscMatlabEnginePut_C",
377a1d52234SKris Buschelman                                            "MatMatlabEnginePut_Matlab",MatMatlabEnginePut_Matlab);CHKERRQ(ierr);
378a1d52234SKris Buschelman   ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"PetscMatlabEngineGet_C",
379a1d52234SKris Buschelman                                            "MatMatlabEngineGet_Matlab",MatMatlabEngineGet_Matlab);CHKERRQ(ierr);
38005db81ecSKris Buschelman   ierr = PetscObjectChangeTypeName((PetscObject)B,MATMATLAB);CHKERRQ(ierr);
38105db81ecSKris Buschelman   *newmat = B;
38205db81ecSKris Buschelman   PetscFunctionReturn(0);
38305db81ecSKris Buschelman }
38405db81ecSKris Buschelman EXTERN_C_END
38505db81ecSKris Buschelman 
38605db81ecSKris Buschelman /*MC
38705db81ecSKris Buschelman   MATMATLAB - MATMATLAB = "matlab" - A matrix type providing direct solvers (LU and QR) and drop tolerance
38805db81ecSKris Buschelman   based ILU factorization (ILUDT) for sequential matrices via the external package Matlab.
38905db81ecSKris Buschelman 
39005db81ecSKris Buschelman   If Matlab is instaled (see the manual for
39105db81ecSKris Buschelman   instructions on how to declare the existence of external packages),
39205db81ecSKris Buschelman   a matrix type can be constructed which invokes Matlab solvers.
39305db81ecSKris Buschelman   After calling MatCreate(...,A), simply call MatSetType(A,MATMATLAB).
39405db81ecSKris Buschelman   This matrix type is only supported for double precision real.
39505db81ecSKris Buschelman 
39605db81ecSKris Buschelman   This matrix inherits from MATSEQAIJ.  As a result, MatSeqAIJSetPreallocation is
39705db81ecSKris Buschelman   supported for this matrix type.  One can also call MatConvert for an inplace conversion to or from
39805db81ecSKris Buschelman   the MATSEQAIJ type without data copy.
39905db81ecSKris Buschelman 
40005db81ecSKris Buschelman   Options Database Keys:
40105db81ecSKris Buschelman + -mat_type matlab - sets the matrix type to "matlab" during a call to MatSetFromOptions()
40205db81ecSKris Buschelman - -mat_matlab_qr   - sets the direct solver to be QR instead of LU
40305db81ecSKris Buschelman 
40405db81ecSKris Buschelman   Level: beginner
40505db81ecSKris Buschelman 
40605db81ecSKris Buschelman .seealso: PCLU
40705db81ecSKris Buschelman M*/
40805db81ecSKris Buschelman 
40905db81ecSKris Buschelman EXTERN_C_BEGIN
41005db81ecSKris Buschelman #undef __FUNCT__
41105db81ecSKris Buschelman #define __FUNCT__ "MatCreate_Matlab"
412*be1d678aSKris Buschelman PetscErrorCode PETSCMAT_DLLEXPORT MatCreate_Matlab(Mat A)
413dfbe8321SBarry Smith {
414dfbe8321SBarry Smith   PetscErrorCode ierr;
4153b3e256bSKris Buschelman 
4163b3e256bSKris Buschelman   PetscFunctionBegin;
41705db81ecSKris Buschelman   ierr = PetscObjectChangeTypeName((PetscObject)A,MATMATLAB);CHKERRQ(ierr);
41805db81ecSKris Buschelman   ierr = MatSetType(A,MATSEQAIJ);CHKERRQ(ierr);
419ceb03754SKris Buschelman   ierr = MatConvert_SeqAIJ_Matlab(A,MATMATLAB,MAT_REUSE_MATRIX,&A);CHKERRQ(ierr);
4203b3e256bSKris Buschelman   PetscFunctionReturn(0);
4213b3e256bSKris Buschelman }
42205db81ecSKris Buschelman EXTERN_C_END
423