Actual source code: normalmat.c
1: #include "normalmat.h" /*I "mat.h" I*/
5: /*@C
6: MatCreateADA - Creates a matrix M=A^T D1 A + D2.
8: Collective on matrix
10: Input Parameters:
11: + mat - matrix of arbitrary type
12: . D1 - A vector
13: - D2 - A vector
15: Output Parameters:
16: . J - New matrix whose operations are defined in terms of mat, D1, and D2.
18: Notes:
19: The user provides the input data and is responsible for destroying
20: this data after matrix J has been destroyed.
21: The operation MatMult(A,D2,D1) must be well defined.
22: Before calling the operation MatGetDiagonal(), the function
23: MatADAComputeDiagonal() must be called. The matrices A and D1 must
24: be the same during calls to MatADAComputeDiagonal() and
25: MatGetDiagonal().
27: Level: developer
29: .seealso: MatCreate()
30: @*/
31: int MatCreateADA(Mat mat,Vec D1, Vec D2, Mat *J)
32: {
33: MPI_Comm comm=mat->comm;
34: TaoMatADACtx ctx;
35: int info,nloc,n;
38: /*
39: info=MatCheckVecs(mat,D1,D2,&flg);CHKERRQ(info);
40: if (flg==PETSC_FALSE){
41: SETERRQ(PETSC_ERR_SUP,"InCompatible matrix and vector for ADA^T matrix");
42: }
43: */
44: info = PetscNew(_p_TaoMatADACtx,&ctx);CHKERRQ(info);
46: ctx->A=mat;
47: ctx->D1=D1;
48: ctx->D2=D2;
49: if (D1){
50: info = VecDuplicate(D1,&ctx->W);CHKERRQ(info);
51: info = PetscObjectReference((PetscObject)D1);CHKERRQ(info);
52: } else {
53: ctx->W=0;
54: }
55: if (D2){
56: info = VecDuplicate(D2,&ctx->W2);CHKERRQ(info);
57: info = VecDuplicate(D2,&ctx->ADADiag);CHKERRQ(info);
58: info = PetscObjectReference((PetscObject)D2);CHKERRQ(info);
59: } else {
60: ctx->W2=0;
61: ctx->ADADiag=0;
62: }
64: ctx->GotDiag=0;
65: info = PetscObjectReference((PetscObject)mat);CHKERRQ(info);
67: info=VecGetLocalSize(D2,&nloc);CHKERRQ(info);
68: info=VecGetSize(D2,&n);CHKERRQ(info);
70: info = MatCreateShell(comm,nloc,nloc,n,n,ctx,J);CHKERRQ(info);
72: info = MatShellSetOperation(*J,MATOP_MULT,(void(*)())MatMult_ADA);CHKERRQ(info);
73: info = MatShellSetOperation(*J,MATOP_DESTROY,(void(*)())MatDestroy_ADA);CHKERRQ(info);
74: info = MatShellSetOperation(*J,MATOP_VIEW,(void(*)())MatView_ADA);CHKERRQ(info);
75: info = MatShellSetOperation(*J,MATOP_MULT_TRANSPOSE,(void(*)())MatMultTranspose_ADA);CHKERRQ(info);
76: info = MatShellSetOperation(*J,MATOP_DIAGONAL_SHIFT,(void(*)())MatDiagonalShift_ADA);CHKERRQ(info);
77: info = MatShellSetOperation(*J,MATOP_SHIFT,(void(*)())MatShift_ADA);CHKERRQ(info);
78: info = MatShellSetOperation(*J,MATOP_EQUAL,(void(*)())MatEqual_ADA);CHKERRQ(info);
79: info = MatShellSetOperation(*J,MATOP_SCALE,(void(*)())MatScale_ADA);CHKERRQ(info);
80: info = MatShellSetOperation(*J,MATOP_TRANSPOSE,(void(*)())MatTranspose_ADA);CHKERRQ(info);
81: info = MatShellSetOperation(*J,MATOP_GET_DIAGONAL,(void(*)())MatGetDiagonal_ADA);CHKERRQ(info);
82: info = MatShellSetOperation(*J,MATOP_GET_SUBMATRICES,(void(*)())MatGetSubMatrices_ADA);CHKERRQ(info);
83: info = MatShellSetOperation(*J,MATOP_NORM,(void(*)())MatNorm_ADA);CHKERRQ(info);
84: info = MatShellSetOperation(*J,MATOP_DUPLICATE,(void(*)())MatDuplicate_ADA);CHKERRQ(info);
85: info = MatShellSetOperation(*J,MATOP_GET_SUBMATRIX,(void(*)())MatGetSubMatrix_ADA);CHKERRQ(info);
87: info = PetscLogObjectParent(*J,ctx->W); CHKERRQ(info);
88: info = PetscLogObjectParent(mat,*J); CHKERRQ(info);
90: info = MatSetOption(*J,MAT_SYMMETRIC);CHKERRQ(info);
91: return(0);
92: }
96: int MatMult_ADA(Mat mat,Vec a,Vec y)
97: {
98: TaoMatADACtx ctx;
99: PetscScalar one = 1.0;
100: int info;
103: info = MatShellGetContext(mat,(void **)&ctx);CHKERRQ(info);
105: info = MatMult(ctx->A,a,ctx->W);CHKERRQ(info);
106: if (ctx->D1){
107: info = VecPointwiseMult(ctx->W,ctx->D1,ctx->W);CHKERRQ(info);
108: }
109: info = MatMultTranspose(ctx->A,ctx->W,y);CHKERRQ(info);
110: if (ctx->D2){
111: info = VecPointwiseMult(ctx->W2, ctx->D2, a);CHKERRQ(info);
112: info = VecAXPY(y, one, ctx->W2);CHKERRQ(info);
113: }
114: return(0);
115: }
119: int MatMultTranspose_ADA(Mat mat,Vec a,Vec y)
120: {
121: int info;
124: info = MatMult_ADA(mat,a,y);CHKERRQ(info);
125: return(0);
126: }
130: int MatDiagonalShift_ADA(Vec D, Mat M)
131: {
132: TaoMatADACtx ctx;
133: PetscScalar zero=0.0,one = 1.0;
134: int info;
137: info = MatShellGetContext(M,(void **)&ctx);CHKERRQ(info);
139: if (ctx->D2==PETSC_NULL){
140: info = VecDuplicate(D,&ctx->D2);CHKERRQ(info);
141: info = VecSet(ctx->D2, zero);CHKERRQ(info);
142: }
143: info = VecAXPY(ctx->D2, one, D);CHKERRQ(info);
145: return(0);
146: }
150: int MatDestroy_ADA(Mat mat)
151: {
152: int info;
153: TaoMatADACtx ctx;
156: info=MatShellGetContext(mat,(void **)&ctx);CHKERRQ(info);
157: info=VecDestroy(ctx->W);CHKERRQ(info);
158: info=VecDestroy(ctx->W2);CHKERRQ(info);
159: info=VecDestroy(ctx->ADADiag);CHKERRQ(info);
160: info=MatDestroy(ctx->A);CHKERRQ(info);
161: info=VecDestroy(ctx->D1);CHKERRQ(info);
162: info=VecDestroy(ctx->D2);CHKERRQ(info);
163: info = PetscFree(ctx); CHKERRQ(info);
164: return(0);
165: }
169: int MatView_ADA(Mat mat,PetscViewer viewer)
170: {
173: /*
174: info = ViewerGetFormat(viewer,&format);CHKERRQ(info);
175: if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_LONG) {
176: return(0); / * do nothing for now * /
177: }
178: info = MatShellGetContext(mat,(void **)&ctx);CHKERRQ(info);
179: info = MatView(ctx->A,viewer);CHKERRQ(info);
180: if (ctx->D1){
181: info = VecView(ctx->D1,viewer);CHKERRQ(info);
182: }
183: if (ctx->D2){
184: info = VecView(ctx->D2,viewer);CHKERRQ(info);
185: }
186: */
187: return(0);
188: }
192: int MatShift_ADA(Mat Y, PetscScalar a)
193: {
194: int info;
195: TaoMatADACtx ctx;
198: info = MatShellGetContext(Y,(void **)&ctx);CHKERRQ(info);
199: info = VecShift(ctx->D2,a);CHKERRQ(info);
200: return(0);
201: }
205: int MatDuplicate_ADA(Mat mat,MatDuplicateOption op,Mat *M)
206: {
207: int info;
208: TaoMatADACtx ctx;
209: Mat A2;
210: Vec D1b=NULL,D2b;
213: info = MatShellGetContext(mat,(void **)&ctx);CHKERRQ(info);
214: info = MatDuplicate(ctx->A,op,&A2);CHKERRQ(info);
215: if (ctx->D1){
216: info = VecDuplicate(ctx->D1,&D1b);CHKERRQ(info);
217: info = VecCopy(ctx->D1,D1b);CHKERRQ(info);
218: }
219: info = VecDuplicate(ctx->D2,&D2b);CHKERRQ(info);
220: info = VecCopy(ctx->D2,D2b);CHKERRQ(info);
221: info = MatCreateADA(A2,D1b,D2b,M);CHKERRQ(info);
222: if (ctx->D1){
223: info = PetscObjectDereference((PetscObject)D1b);CHKERRQ(info);
224: }
225: info = PetscObjectDereference((PetscObject)D2b);CHKERRQ(info);
226: info = PetscObjectDereference((PetscObject)A2);CHKERRQ(info);
228: return(0);
229: }
233: int MatEqual_ADA(Mat A,Mat B,PetscTruth *flg)
234: {
235: int info;
236: TaoMatADACtx ctx1,ctx2;
239: info = MatShellGetContext(A,(void **)&ctx1);CHKERRQ(info);
240: info = MatShellGetContext(B,(void **)&ctx2);CHKERRQ(info);
241: info = VecEqual(ctx1->D2,ctx2->D2,flg);CHKERRQ(info);
242: if (*flg==PETSC_TRUE){
243: info = VecEqual(ctx1->D1,ctx2->D1,flg);CHKERRQ(info);
244: }
245: if (*flg==PETSC_TRUE){
246: info = MatEqual(ctx1->A,ctx2->A,flg);CHKERRQ(info);
247: }
248: return(0);
249: }
253: int MatScale_ADA(Mat mat, PetscScalar a)
254: {
255: int info;
256: TaoMatADACtx ctx;
259: info = MatShellGetContext(mat,(void **)&ctx);CHKERRQ(info);
260: info = VecScale(ctx->D1,a);CHKERRQ(info);
261: if (ctx->D2){
262: info = VecScale(ctx->D2,a);CHKERRQ(info);
263: }
264: return(0);
265: }
269: int MatTranspose_ADA(Mat mat,Mat *B)
270: {
271: int info;
272: TaoMatADACtx ctx;
275: if (*B){
276: info = MatShellGetContext(mat,(void **)&ctx);CHKERRQ(info);
277: info = MatDuplicate(mat,MAT_COPY_VALUES,B);CHKERRQ(info);
278: }
279: return(0);
280: }
284: int MatADAComputeDiagonal(Mat mat)
285: {
286: int i,m,n,low,high,info;
287: PetscScalar *dtemp,*dptr;
288: TaoMatADACtx ctx;
291: info = MatShellGetContext(mat,(void **)&ctx);CHKERRQ(info);
293: info = MatGetOwnershipRange(mat, &low, &high);CHKERRQ(info);
294: info = MatGetSize(mat,&m,&n);CHKERRQ(info);
295:
296: info = PetscMalloc( n*sizeof(PetscScalar),&dtemp ); CHKERRQ(info);
298: for (i=0; i<n; i++){
299: info = MatGetColumnVector(ctx->A, ctx->W, i);CHKERRQ(info);
300: info = VecPointwiseMult(ctx->W,ctx->W,ctx->W);CHKERRQ(info);
301: info = VecDotBegin(ctx->D1, ctx->W,dtemp+i);CHKERRQ(info);
302: }
303: for (i=0; i<n; i++){
304: info = VecDotEnd(ctx->D1, ctx->W,dtemp+i);CHKERRQ(info);
305: }
307: info = VecGetArray(ctx->ADADiag,&dptr);CHKERRQ(info);
308: for (i=low; i<high; i++){
309: dptr[i-low]= dtemp[i];
310: }
311: info = VecRestoreArray(ctx->ADADiag,&dptr);CHKERRQ(info);
312: if (dtemp) {
313: info = PetscFree(dtemp); CHKERRQ(info);
314: }
315: return(0);
316: }
320: int MatGetDiagonal_ADA(Mat mat,Vec v)
321: {
322: int info;
323: PetscScalar one=1.0;
324: TaoMatADACtx ctx;
327: info = MatShellGetContext(mat,(void **)&ctx);CHKERRQ(info);
328: info = MatADAComputeDiagonal(mat);
329: info=VecCopy(ctx->ADADiag,v);CHKERRQ(info);
330: if (ctx->D2){
331: info=VecAXPY(v, one, ctx->D2);CHKERRQ(info);
332: }
334: return(0);
335: }
339: int MatGetSubMatrices_ADA(Mat A,int n, IS *irow,IS *icol,MatReuse scall,Mat **B)
340: {
341: int info,i;
344: if (scall == MAT_INITIAL_MATRIX) {
345: info = PetscMalloc( (n+1)*sizeof(Mat),B );CHKERRQ(info);
346: }
348: for ( i=0; i<n; i++ ) {
349: info = MatGetSubMatrix_ADA(A,irow[i],icol[i],PETSC_DECIDE,scall,&(*B)[i]);CHKERRQ(info);
350: }
351: return(0);
352: }
356: int MatGetSubMatrix_ADA(Mat mat,IS isrow,IS iscol,int csize,MatReuse cll,
357: Mat *newmat)
358: {
359: int info,low,high;
360: int n,nlocal,i;
361: int *iptr;
362: PetscScalar *dptr,*ddptr,zero=0.0;
363: VecType type_name;
364: IS ISrow;
365: Vec D1,D2;
366: Mat Atemp;
367: TaoMatADACtx ctx;
371: info = MatShellGetContext(mat,(void **)&ctx);CHKERRQ(info);
373: info = MatGetOwnershipRange(ctx->A,&low,&high);CHKERRQ(info);
374: info = ISCreateStride(mat->comm,high-low,low,1,&ISrow);CHKERRQ(info);
375: info = MatGetSubMatrix(ctx->A,ISrow,iscol,csize,cll,&Atemp);CHKERRQ(info);
376: info = ISDestroy(ISrow);CHKERRQ(info);
378: if (ctx->D1){
379: info=VecDuplicate(ctx->D1,&D1);CHKERRQ(info);
380: info=VecCopy(ctx->D1,D1);CHKERRQ(info);
381: } else {
382: D1=PETSC_NULL;
383: }
385: if (ctx->D2){
386: info=ISGetSize(isrow,&n);CHKERRQ(info);
387: info=ISGetLocalSize(isrow,&nlocal);CHKERRQ(info);
388: info=VecCreate(ctx->D2->comm,&D2);CHKERRQ(info);
389: info=VecGetType(ctx->D2,&type_name);CHKERRQ(info);
390: info=VecSetSizes(D2,nlocal,n);CHKERRQ(info);
391: info=VecSetType(D2,type_name);CHKERRQ(info);
392: info=VecSet(D2, zero);CHKERRQ(info);
393: info=VecGetArray(ctx->D2, &dptr); CHKERRQ(info);
394: info=VecGetArray(D2, &ddptr); CHKERRQ(info);
395: info=ISGetIndices(isrow,&iptr); CHKERRQ(info);
396: for (i=0;i<nlocal;i++){
397: ddptr[i] = dptr[iptr[i]-low];
398: }
399: info=ISRestoreIndices(isrow,&iptr); CHKERRQ(info);
400: info=VecRestoreArray(D2, &ddptr); CHKERRQ(info);
401: info=VecRestoreArray(ctx->D2, &dptr); CHKERRQ(info);
402:
403: } else {
404: D2=PETSC_NULL;
405: }
407: info = MatCreateADA(Atemp,D1,D2,newmat);CHKERRQ(info);
408: info = MatShellGetContext(*newmat,(void **)&ctx);CHKERRQ(info);
409: info = PetscObjectDereference((PetscObject)Atemp);CHKERRQ(info);
410: if (ctx->D1){
411: info = PetscObjectDereference((PetscObject)D1);CHKERRQ(info);
412: }
413: if (ctx->D2){
414: info = PetscObjectDereference((PetscObject)D2);CHKERRQ(info);
415: }
416: return(0);
417: }
421: int MatGetRowADA(Mat mat,int row,int *ncols,int **cols,PetscScalar **vals)
422: {
423: int info,m,n;
426: info = MatGetSize(mat,&m,&n);CHKERRQ(info);
428: if (*ncols>0){
429: info = PetscMalloc( (*ncols)*sizeof(int),cols );CHKERRQ(info);
430: info = PetscMalloc( (*ncols)*sizeof(PetscScalar),vals );CHKERRQ(info);
431: } else {
432: *cols=PETSC_NULL;
433: *vals=PETSC_NULL;
434: }
435:
436: return(0);
437: }
441: int MatRestoreRowADA(Mat mat,int row,int *ncols,int **cols,PetscScalar **vals)
442: {
443: int info;
445: if (*ncols>0){
446: info = PetscFree(*cols); CHKERRQ(info);
447: info = PetscFree(*vals); CHKERRQ(info);
448: }
449: *cols=PETSC_NULL;
450: *vals=PETSC_NULL;
451: return(0);
452: }
456: int MatGetColumnVector_ADA(Mat mat,Vec Y, int col)
457: {
458: int info,low,high;
459: PetscScalar zero=0.0,one=1.0;
462: info=VecSet(Y, zero);CHKERRQ(info);
463: info=VecGetOwnershipRange(Y,&low,&high);CHKERRQ(info);
464: if (col>=low && col<high){
465: info=VecSetValue(Y,col,one,INSERT_VALUES);CHKERRQ(info);
466: }
467: info=VecAssemblyBegin(Y);CHKERRQ(info);
468: info=VecAssemblyEnd(Y);CHKERRQ(info);
469: info=MatMult_ADA(mat,Y,Y);CHKERRQ(info);
471: return(0);
472: }
474: int MatConvert_ADA(Mat mat,MatType newtype,Mat *NewMat)
475: {
476: int info,size;
477: TaoMatADACtx ctx;
480: info = MatShellGetContext(mat,(void **)&ctx);CHKERRQ(info);
481: MPI_Comm_size(mat->comm,&size);
483: if (newtype==MATSAME){
485: info=MatDuplicate(mat,MAT_COPY_VALUES,NewMat);CHKERRQ(info);
487: } else if (newtype==MATMPIDENSE){
489: int i,j,low,high,m,n,M,N;
490: PetscScalar *dptr;
491: Vec X;
493: info = VecDuplicate(ctx->D2,&X);CHKERRQ(info);
494: info=MatGetSize(mat,&M,&N);CHKERRQ(info);
495: info=MatGetLocalSize(mat,&m,&n);CHKERRQ(info);
496: info = MatCreateMPIDense(mat->comm,m,m,N,N,PETSC_NULL,NewMat);
497: CHKERRQ(info);
498: info = MatGetOwnershipRange(*NewMat,&low,&high);CHKERRQ(info);
499: for (i=0;i<M;i++){
500: info = MatGetColumnVector_ADA(mat,X,i);CHKERRQ(info);
501: info = VecGetArray(X,&dptr);CHKERRQ(info);
502: for (j=0; j<high-low; j++){
503: info = MatSetValue(*NewMat,low+j,i,dptr[j],INSERT_VALUES);CHKERRQ(info);
504: }
505: info=VecRestoreArray(X,&dptr);CHKERRQ(info);
506: }
507: info=MatAssemblyBegin(*NewMat,MAT_FINAL_ASSEMBLY);CHKERRQ(info);
508: info=MatAssemblyEnd(*NewMat,MAT_FINAL_ASSEMBLY);CHKERRQ(info);
509: info = VecDestroy(X);CHKERRQ(info);
511: } else if (newtype==MATSEQDENSE && size==1){
513: int i,j,low,high,m,n,M,N;
514: PetscScalar *dptr;
515: Vec X;
517: info = VecDuplicate(ctx->D2,&X);CHKERRQ(info);
518: info = MatGetSize(mat,&M,&N);CHKERRQ(info);
519: info = MatGetLocalSize(mat,&m,&n);CHKERRQ(info);
520: info = MatCreateSeqDense(mat->comm,N,N,PETSC_NULL,NewMat);
521: CHKERRQ(info);
522: info = MatGetOwnershipRange(*NewMat,&low,&high);CHKERRQ(info);
523: for (i=0;i<M;i++){
524: info = MatGetColumnVector_ADA(mat,X,i);CHKERRQ(info);
525: info = VecGetArray(X,&dptr);CHKERRQ(info);
526: for (j=0; j<high-low; j++){
527: info = MatSetValue(*NewMat,low+j,i,dptr[j],INSERT_VALUES);CHKERRQ(info);
528: }
529: info=VecRestoreArray(X,&dptr);CHKERRQ(info);
530: }
531: info=MatAssemblyBegin(*NewMat,MAT_FINAL_ASSEMBLY);CHKERRQ(info);
532: info=MatAssemblyEnd(*NewMat,MAT_FINAL_ASSEMBLY);CHKERRQ(info);
533: info=VecDestroy(X);CHKERRQ(info);
535: } else {
536: SETERRQ(1,"No support to convert objects to that type");
537: }
538: return(0);
539: }
543: int MatNorm_ADA(Mat mat,NormType type,PetscReal *norm)
544: {
545: int info;
546: TaoMatADACtx ctx;
549: info = MatShellGetContext(mat,(void **)&ctx);CHKERRQ(info);
551: if (type == NORM_FROBENIUS) {
552: *norm = 1.0;
553: } else if (type == NORM_1 || type == NORM_INFINITY) {
554: *norm = 1.0;
555: } else {
556: SETERRQ(PETSC_ERR_SUP,"No two norm");
557: }
558: return(0);
559: }