[petsc-users] Advice on how to tackle with in place operation for a Matrix

Umut Tabak u.tabak at tudelft.nl
Tue May 18 02:52:33 CDT 2010


Dear all,

I would like to do a Gram-Schmidt orthogonalization of a matrix with say 
10 columns, I wrote a function for this, However, I do not do this in 
place for the moment. I create a new matrix for the orthogonal(or 
M-orthogonal columns). And set the columns of that new matrix, I could 
not see how I could do this in place, where I read the original matrix 
in binary format from a file. Then its assembly is finalized I suppose, 
is there still a way to make changes on that matrix in place?

The code is below.

A simple translation of a matlab script(more efficient implementations 
are possible I am sure.)

int mgrasch_Morth(Mat &inMat, Mat &outMat, Mat M )
{
  // read size of the matrix
  PetscErrorCode ierr;
  PetscInt r,c;
  ierr = MatGetSize(inMat, &r, 
&c);                                          CHKERRQ(ierr);
  ierr = MatDuplicate(inMat, MAT_COPY_VALUES, &outMat); CHKERRQ(ierr);
  // set up the necessary workspace
  Vec Q,R,dummy1,dummy2,dummy3,orthoVec;
  PetscScalar val1, val2;
  //
  ierr = VecCreate(MPI_COMM_SELF, &Q);     CHKERRQ(ierr);
  ierr = VecCreate(MPI_COMM_SELF, &R);     CHKERRQ(ierr);

  // dummy vectors for matrix multiplication
  ierr = VecCreate(MPI_COMM_SELF, &dummy1);     CHKERRQ(ierr);
  ierr = VecCreate(MPI_COMM_SELF, &dummy2);     CHKERRQ(ierr);
  ierr = VecCreate(MPI_COMM_SELF, &dummy2);     CHKERRQ(ierr);
  ierr = VecCreate(MPI_COMM_SELF, &dummy3);     CHKERRQ(ierr);
  //
  ierr = VecCreate(MPI_COMM_SELF, &orthoVec);     CHKERRQ(ierr);
  //
  ierr = VecSetSizes(Q, r, PETSC_DECIDE);  CHKERRQ(ierr);
  ierr = VecSetSizes(R, r, PETSC_DECIDE);  CHKERRQ(ierr);
  ierr = VecSetSizes(dummy1, r, PETSC_DECIDE);  CHKERRQ(ierr);
  ierr = VecSetSizes(dummy2, r, PETSC_DECIDE);  CHKERRQ(ierr);
  ierr = VecSetSizes(dummy3, r, PETSC_DECIDE);  CHKERRQ(ierr);
  ierr = VecSetSizes(orthoVec, r, PETSC_DECIDE);  CHKERRQ(ierr);
  //
  ierr = VecSetFromOptions(R);         CHKERRQ(ierr);
  ierr = VecSetFromOptions(Q);         CHKERRQ(ierr);
  ierr = VecSetFromOptions(dummy1);    CHKERRQ(ierr); // for M * A(:,m)
  ierr = VecSetFromOptions(dummy2);    CHKERRQ(ierr); // for M * Q
  ierr = VecSetFromOptions(dummy3);    CHKERRQ(ierr); // for A(:,m) above
  ierr = VecSetFromOptions(orthoVec);  CHKERRQ(ierr); //  orthogonalized 
result vec
  // create the arrays for MatSetValues
  // row
  PetscInt rowArr[r];
  for(int k=0;k!=r;k++)
    rowArr[k]=k;
  // to set one column at a time
  PetscInt C = 1;
  PetscInt colArr[1];
  PetscScalar valsOrthoVec[r];
  //
  for(int i=0;i!=c;i++){
    MatGetColumnVector(inMat, Q, i);
    for(int j=i+1;j!=c;j++){
      ierr = MatGetColumnVector(inMat, dummy3, j); CHKERRQ(ierr);
     ierr = MatMult(M,dummy3,dummy1);             CHKERRQ(ierr);
      // val1 -> Q'* M * A(:,m)
      ierr = VecTDot(Q, dummy1,&val1);             CHKERRQ(ierr);
      ierr = MatMult(M,Q,dummy2);                  CHKERRQ(ierr);
      // val2 -> Q'* M * Q
      ierr = VecTDot(Q,dummy2,&val2);              CHKERRQ(ierr);
      //
      ierr = VecAXPY(dummy3, -val1/val2, Q);       CHKERRQ(ierr);
      ierr = VecCopy(dummy3, orthoVec);            CHKERRQ(ierr);
      // set the orthogonal vector
      colArr[0] = j;
      //
      ierr = VecGetValues(orthoVec, r, rowArr, 
valsOrthoVec);                                           CHKERRQ(ierr);
      ierr = MatSetValues(outMat, r, rowArr, C, colArr, valsOrthoVec, 
INSERT_VALUES);  CHKERRQ(ierr);
    }
  }
  ierr = MatAssemblyBegin(outMat, MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
  ierr = MatAssemblyEnd(outMat, MAT_FINAL_ASSEMBLY);   CHKERRQ(ierr);
  return 0;
}



More information about the petsc-users mailing list