docs: def decompose(self,
              noise=False,
              verbosity=0,
              logic='or',
              **kwargs):
          """ Use prune to remove links between distant points:
  
          prune is None: no pruning
          prune={int > 0}: prunes links beyond `prune` nearest neighbours
          prune='estimate': searches for the smallest value that retains a fully
          connected graph
  
          """
          matrix = self.get_dm(noise)
  
          # get local scale estimate
          est_scale = None
  
          # ADJUST MASK
          if self._pruning_option == options.PRUNING_NONE:  
              # Set kp to max value
              kp = len(matrix) - 1
              mask = np.ones(matrix.shape, dtype=bool)
          elif self._pruning_option == options.PRUNING_MANUAL:
              # Manually set value of kp
              kp = self._manual_pruning
              mask = kmask(matrix, self._manual_pruning, logic=logic)
          elif self._pruning_option == options.PRUNING_ESTIMATE:
              # Must estimate value of kp
              kp, mask, est_scale = binsearch_mask(matrix, logic=logic) 
          else:
              raise ValueError("Unexpected error: 'kp' not set")
  
          # ADJUST SCALE
          if self._scale_option == options.LOCAL_SCALE_MEDIAN:
              dist = np.median(matrix, axis=1)
              scale = np.outer(dist, dist)
          elif self._scale_option == options.LOCAL_SCALE_MANUAL:
              scale = kscale(matrix, self._manual_scale)
          elif self._scale_option == options.LOCAL_SCALE_ESTIMATE:
              if est_scale is None:
                  _, _, scale = binsearch_mask(matrix, logic=logic) 
              else:
                  # Nothing to be done - est_scale was set during the PRUNING_ESTIMATE
                  scale = est_scale
          else:
              raise ValueError("Unexpected error: 'scale' not set")
  
          # ZeroDivisionError safety check
          if not (scale > 1e-5).all():
              if verbosity > 0:
                  print('Rescaling to avoid zero-div error')
              _, _, scale = binsearch_mask(matrix, logic=logic)
              assert (scale > 1e-5).all()
  
          aff = affinity(matrix, mask, scale)
          aff.flat[::len(aff)+1] = 1.0
          return aff