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: }