code: def dstep(self, W):
          
  
          # Compute residual X D - S in frequency domain
          Ryf = sl.inner(self.Zf, self.Df, axis=self.cri.axisM) - self.Sf
          # Transform to spatial domain, apply mask, and transform back to
          # frequency domain
          Ryf[:] = sl.rfftn(W * sl.irfftn(Ryf, self.cri.Nv, self.cri.axisN),
                            None, self.cri.axisN)
          # Compute gradient
          gradf = sl.inner(np.conj(self.Zf), Ryf, axis=self.cri.axisK)
  
          # If multiple channel signal, single channel dictionary
          if self.cri.C > 1 and self.cri.Cd == 1:
              gradf = np.sum(gradf, axis=self.cri.axisC, keepdims=True)
  
          # Update gradient step
          self.eta = self.eta_a / (self.j + self.eta_b)
  
          # Compute gradient descent
          self.Gf[:] = self.Df - self.eta * gradf
          self.G = sl.irfftn(self.Gf, self.cri.Nv, self.cri.axisN)
  
          # Eval proximal operator
          self.Dprv[:] = self.D
          self.D[:] = self.Pcn(self.G)
docs: Compute dictionary update for training data of preceding
          :meth:`xstep`.