Actual source code: softthreshold.c

  1: #include <petsc/private/taoimpl.h>

  3: /*@
  4:   TaoSoftThreshold - Calculates soft thresholding routine with input vector
  5:   and given lower and upper bound and returns it to output vector.

  7:   Collective

  9:   Input Parameters:
 10: + in - input vector to be thresholded
 11: . lb - lower bound
 12: - ub - upper bound

 14:   Output Parameter:
 15: . out - Soft thresholded output vector

 17:   Notes:
 18:   Soft thresholding is defined as
 19:   \[ S(input,lb,ub) =
 20:   \begin{cases}
 21:   input - ub  & \text{if } input > ub \\
 22:   0           & \text{if } lb \leq input \leq ub \\
 23:   input - lb  & \text{if } input < lb
 24:   \end{cases}
 25:   \]

 27:   Level: developer

 29: .seealso: `Tao`, `Vec`
 30: @*/
 31: PetscErrorCode TaoSoftThreshold(Vec in, PetscReal lb, PetscReal ub, Vec out)
 32: {
 33:   PetscInt     i, nlocal, mlocal;
 34:   PetscScalar *inarray, *outarray;

 36:   PetscFunctionBegin;
 39:   PetscCheck(lb <= ub, PETSC_COMM_SELF, PETSC_ERR_ARG_INCOMP, "Lower bound needs to be lower than upper bound");
 40:   if (lb == ub) {
 41:     PetscCall(VecCopy(in, out));
 42:     PetscCall(VecShift(out, -lb));
 43:     PetscFunctionReturn(PETSC_SUCCESS);
 44:   }

 46:   PetscCall(VecGetLocalSize(in, &nlocal));
 47:   PetscCall(VecGetLocalSize(out, &mlocal));
 48:   PetscCheck(nlocal == mlocal, PETSC_COMM_SELF, PETSC_ERR_ARG_INCOMP, "Input and output vectors need to be of same size");
 49:   PetscCall(VecGetArrayPair(in, out, &inarray, &outarray));

 51:   for (i = 0; i < nlocal; i++) outarray[i] = PetscMax(0, PetscRealPart(inarray[i]) - ub) + PetscMin(0, PetscRealPart(inarray[i]) - lb);

 53:   PetscCall(VecRestoreArrayPair(in, out, &inarray, &outarray));
 54:   PetscFunctionReturn(PETSC_SUCCESS);
 55: }