PetscErrorCode MatMultHermitianAdd_Normal(Mat N,Vec v1,Vec v2,Vec v3) { Mat_Normal *Na = (Mat_Normal*)N->data; PetscErrorCode ierr; Vec in; PetscFunctionBegin; in = v1; if (Na->right) { if (!Na->rightwork) { ierr = VecDuplicate(Na->right,&Na->rightwork);CHKERRQ(ierr); } ierr = VecPointwiseMult(Na->rightwork,Na->right,in);CHKERRQ(ierr); in = Na->rightwork; } ierr = MatMult(Na->A,in,Na->w);CHKERRQ(ierr); ierr = VecScale(Na->w,Na->scale);CHKERRQ(ierr); if (Na->left) { ierr = MatMultHermitianTranspose(Na->A,Na->w,v3);CHKERRQ(ierr); ierr = VecPointwiseMult(v3,Na->left,v3);CHKERRQ(ierr); ierr = VecAXPY(v3,1.0,v2);CHKERRQ(ierr); } else { ierr = MatMultHermitianTransposeAdd(Na->A,Na->w,v2,v3);CHKERRQ(ierr); } PetscFunctionReturn(0); }
static void PETScMatvecGenNoBlock(void *x, PRIMME_INT ldx, void *y, PRIMME_INT ldy, int blockSize, int trans, Mat matrix, MPI_Comm comm) { int i; Vec xvec, yvec; PetscInt m, n, mLocal, nLocal; PetscErrorCode ierr; assert(sizeof(PetscScalar) == sizeof(SCALAR)); ierr = MatGetSize(matrix, &m, &n); CHKERRABORT(comm, ierr); ierr = MatGetLocalSize(matrix, &mLocal, &nLocal); CHKERRABORT(comm, ierr); #if PETSC_VERSION_LT(3,6,0) ierr = MatGetVecs(matrix, &xvec, &yvec); CHKERRABORT(comm, ierr); #else ierr = MatCreateVecs(matrix, &xvec, &yvec); CHKERRABORT(comm, ierr); #endif if (trans == 1) { Vec aux = xvec; xvec = yvec; yvec = aux; } for (i=0; i<blockSize; i++) { ierr = VecPlaceArray(xvec, ((SCALAR*)x) + ldx*i); CHKERRABORT(comm, ierr); ierr = VecPlaceArray(yvec, ((SCALAR*)y) + ldy*i); CHKERRABORT(comm, ierr); if (trans == 0) { ierr = MatMult(matrix, xvec, yvec); CHKERRABORT(comm, ierr); } else { ierr = MatMultHermitianTranspose(matrix, xvec, yvec); CHKERRABORT(comm, ierr); } ierr = VecResetArray(xvec); CHKERRABORT(comm, ierr); ierr = VecResetArray(yvec); CHKERRABORT(comm, ierr); } ierr = VecDestroy(&xvec); CHKERRABORT(comm, ierr); ierr = VecDestroy(&yvec); CHKERRABORT(comm, ierr); }
PetscErrorCode MatMult_HT(Mat N,Vec x,Vec y) { Mat_HT *Na = (Mat_HT*)N->data; PetscErrorCode ierr; PetscFunctionBegin; ierr = MatMultHermitianTranspose(Na->A,x,y);CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode _g2_ts_monitor(TS ts,PetscInt step,PetscReal time,Vec dm,void *ctx){ TSCtx *tsctx = (TSCtx*) ctx; /* user-defined application context */ PetscScalar ev; if (tsctx->tau_evolve==1){ MatMult(tsctx->I_cross_A,dm,tsctx->tmp_dm); // tmp = I \cross A \rho MatMultHermitianTranspose(tsctx->I_cross_A,tsctx->tmp_dm,tsctx->tmp_dm2); // tmp2 = I \cross A^\dag tmp trace_dm(&ev,tsctx->tmp_dm2); tsctx->g2_values[tsctx->i_st][tsctx->i_tau] += ev; tsctx->i_tau = tsctx->i_tau + 1; } PetscFunctionReturn(0); }
/*@ SVDComputeResidualNorms - Computes the norms of the residual vectors associated with the i-th computed singular triplet. Collective on SVD Input Parameters: + svd - the singular value solver context - i - the solution index Output Parameters: + norm1 - the norm ||A*v-sigma*u||_2 where sigma is the singular value, u and v are the left and right singular vectors. - norm2 - the norm ||A^T*u-sigma*v||_2 with the same sigma, u and v Note: The index i should be a value between 0 and nconv-1 (see SVDGetConverged()). Both output parameters can be NULL on input if not needed. Level: beginner .seealso: SVDSolve(), SVDGetConverged(), SVDComputeRelativeError() @*/ PetscErrorCode SVDComputeResidualNorms(SVD svd,PetscInt i,PetscReal *norm1,PetscReal *norm2) { PetscErrorCode ierr; Vec u,v,x = NULL,y = NULL; PetscReal sigma; PetscInt M,N; PetscFunctionBegin; PetscValidHeaderSpecific(svd,SVD_CLASSID,1); PetscValidLogicalCollectiveInt(svd,i,2); if (svd->reason == SVD_CONVERGED_ITERATING) SETERRQ(PetscObjectComm((PetscObject)svd),PETSC_ERR_ARG_WRONGSTATE,"SVDSolve must be called first"); if (i<0 || i>=svd->nconv) SETERRQ(PetscObjectComm((PetscObject)svd),PETSC_ERR_ARG_OUTOFRANGE,"Argument 2 out of range"); ierr = MatGetVecs(svd->OP,&v,&u);CHKERRQ(ierr); ierr = SVDGetSingularTriplet(svd,i,&sigma,u,v);CHKERRQ(ierr); if (norm1) { ierr = VecDuplicate(u,&x);CHKERRQ(ierr); ierr = MatMult(svd->OP,v,x);CHKERRQ(ierr); ierr = VecAXPY(x,-sigma,u);CHKERRQ(ierr); ierr = VecNorm(x,NORM_2,norm1);CHKERRQ(ierr); } if (norm2) { ierr = VecDuplicate(v,&y);CHKERRQ(ierr); if (svd->A && svd->AT) { ierr = MatGetSize(svd->OP,&M,&N);CHKERRQ(ierr); if (M<N) { ierr = MatMult(svd->A,u,y);CHKERRQ(ierr); } else { ierr = MatMult(svd->AT,u,y);CHKERRQ(ierr); } } else { #if defined(PETSC_USE_COMPLEX) ierr = MatMultHermitianTranspose(svd->OP,u,y);CHKERRQ(ierr); #else ierr = MatMultTranspose(svd->OP,u,y);CHKERRQ(ierr); #endif } ierr = VecAXPY(y,-sigma,v);CHKERRQ(ierr); ierr = VecNorm(y,NORM_2,norm2);CHKERRQ(ierr); } ierr = VecDestroy(&v);CHKERRQ(ierr); ierr = VecDestroy(&u);CHKERRQ(ierr); ierr = VecDestroy(&x);CHKERRQ(ierr); ierr = VecDestroy(&y);CHKERRQ(ierr); PetscFunctionReturn(0); }
void PetscVector<T>::add_vector_conjugate_transpose (const NumericVector<T>& V_in, const SparseMatrix<T>& A_in) { this->_restore_array(); // Make sure the data passed in are really of Petsc types const PetscVector<T>* V = libmesh_cast_ptr<const PetscVector<T>*>(&V_in); const PetscMatrix<T>* A = libmesh_cast_ptr<const PetscMatrix<T>*>(&A_in); A->close(); // Store a temporary copy since MatMultHermitianTransposeAdd doesn't seem to work // TODO: Find out why MatMultHermitianTransposeAdd doesn't work, might be a PETSc bug? AutoPtr< NumericVector<Number> > this_clone = this->clone(); // The const_cast<> is not elegant, but it is required since PETSc // is not const-correct. PetscErrorCode ierr = MatMultHermitianTranspose(const_cast<PetscMatrix<T>*>(A)->mat(), V->_vec, _vec); CHKERRABORT(libMesh::COMM_WORLD,ierr); // Add the temporary copy to the matvec result this->add(1., *this_clone); }
PetscErrorCode MatMultHermitian_Normal(Mat N,Vec x,Vec y) { Mat_Normal *Na = (Mat_Normal*)N->data; PetscErrorCode ierr; Vec in; PetscFunctionBegin; in = x; if (Na->right) { if (!Na->rightwork) { ierr = VecDuplicate(Na->right,&Na->rightwork);CHKERRQ(ierr); } ierr = VecPointwiseMult(Na->rightwork,Na->right,in);CHKERRQ(ierr); in = Na->rightwork; } ierr = MatMult(Na->A,in,Na->w);CHKERRQ(ierr); ierr = MatMultHermitianTranspose(Na->A,Na->w,y);CHKERRQ(ierr); if (Na->left) { ierr = VecPointwiseMult(y,Na->left,y);CHKERRQ(ierr); } ierr = VecScale(y,Na->scale);CHKERRQ(ierr); PetscFunctionReturn(0); }