1c1fff1c6SRichard Tran Mills 2c1fff1c6SRichard Tran Mills #include <petsc/private/matimpl.h> /*I "petscmat.h" I*/ 3c1fff1c6SRichard Tran Mills 4*9371c9d4SSatish Balay PetscErrorCode MatMult_Centering(Mat A, Vec xx, Vec yy) { 5c1fff1c6SRichard Tran Mills PetscScalar *y; 6c1fff1c6SRichard Tran Mills const PetscScalar *x; 7c1fff1c6SRichard Tran Mills PetscScalar sum, mean; 8c1fff1c6SRichard Tran Mills PetscInt i, m = A->rmap->n, size; 9c1fff1c6SRichard Tran Mills 10c1fff1c6SRichard Tran Mills PetscFunctionBegin; 119566063dSJacob Faibussowitsch PetscCall(VecSum(xx, &sum)); 129566063dSJacob Faibussowitsch PetscCall(VecGetSize(xx, &size)); 13c1fff1c6SRichard Tran Mills mean = sum / (PetscScalar)size; 149566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(xx, &x)); 159566063dSJacob Faibussowitsch PetscCall(VecGetArray(yy, &y)); 16*9371c9d4SSatish Balay for (i = 0; i < m; i++) { y[i] = x[i] - mean; } 179566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(xx, &x)); 189566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(yy, &y)); 19c1fff1c6SRichard Tran Mills PetscFunctionReturn(0); 20c1fff1c6SRichard Tran Mills } 21c1fff1c6SRichard Tran Mills 22c1fff1c6SRichard Tran Mills /*@ 23c1fff1c6SRichard Tran Mills MatCreateCentering - Creates a new matrix object that implements the (symmetric and idempotent) centering matrix, I - (1/N) * ones*ones' 24c1fff1c6SRichard Tran Mills 25c1fff1c6SRichard Tran Mills Collective on Mat 26c1fff1c6SRichard Tran Mills 27c1fff1c6SRichard Tran Mills Input Parameters: 28c1fff1c6SRichard Tran Mills + comm - MPI communicator 29c1fff1c6SRichard Tran Mills . n - number of local rows (or PETSC_DECIDE to have calculated if N is given) 30c1fff1c6SRichard Tran Mills This value should be the same as the local size used in creating the 31c1fff1c6SRichard Tran Mills y vector for the matrix-vector product y = Ax. 32c1fff1c6SRichard Tran Mills - N - number of global rows (or PETSC_DETERMINE to have calculated if n is given) 33c1fff1c6SRichard Tran Mills 34c1fff1c6SRichard Tran Mills Output Parameter: 35c1fff1c6SRichard Tran Mills . C - the matrix 36c1fff1c6SRichard Tran Mills 37c1fff1c6SRichard Tran Mills Notes: 38c1fff1c6SRichard Tran Mills The entries of the matrix C are not explicitly stored. Instead, the new matrix 39c1fff1c6SRichard Tran Mills object is a shell that simply performs the action of the centering matrix, i.e., 40c1fff1c6SRichard Tran Mills multiplying C*x subtracts the mean of the vector x from each of its elements. 41c1fff1c6SRichard Tran Mills This is useful for preserving sparsity when mean-centering the columns of a 42c1fff1c6SRichard Tran Mills matrix is required. For instance, to perform principal components analysis with 43c1fff1c6SRichard Tran Mills a matrix A, the composite matrix C*A can be passed to a partial SVD solver. 44c1fff1c6SRichard Tran Mills 45c1fff1c6SRichard Tran Mills Level: intermediate 46c1fff1c6SRichard Tran Mills 47db781477SPatrick Sanan .seealso: `MatCreateLRC()`, `MatCreateComposite()` 48c1fff1c6SRichard Tran Mills @*/ 49*9371c9d4SSatish Balay PetscErrorCode MatCreateCentering(MPI_Comm comm, PetscInt n, PetscInt N, Mat *C) { 50c1fff1c6SRichard Tran Mills PetscMPIInt size; 51c1fff1c6SRichard Tran Mills 52c1fff1c6SRichard Tran Mills PetscFunctionBegin; 539566063dSJacob Faibussowitsch PetscCall(MatCreate(comm, C)); 549566063dSJacob Faibussowitsch PetscCall(MatSetSizes(*C, n, n, N, N)); 559566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(comm, &size)); 569566063dSJacob Faibussowitsch PetscCall(PetscObjectChangeTypeName((PetscObject)*C, MATCENTERING)); 57c1fff1c6SRichard Tran Mills 58c1fff1c6SRichard Tran Mills (*C)->ops->mult = MatMult_Centering; 59c1fff1c6SRichard Tran Mills (*C)->assembled = PETSC_TRUE; 60c1fff1c6SRichard Tran Mills (*C)->preallocated = PETSC_TRUE; 61b94d7dedSBarry Smith (*C)->symmetric = PETSC_BOOL3_TRUE; 62b94d7dedSBarry Smith (*C)->symmetry_eternal = PETSC_TRUE; 63b94d7dedSBarry Smith (*C)->structural_symmetry_eternal = PETSC_TRUE; 649566063dSJacob Faibussowitsch PetscCall(MatSetUp(*C)); 65c1fff1c6SRichard Tran Mills PetscFunctionReturn(0); 66c1fff1c6SRichard Tran Mills } 67