docs: def build_landmark_op(self):
          """Build the landmark operator
  
          Calculates spectral clusters on the kernel, and calculates transition
          probabilities between cluster centers by using transition probabilities
          between samples assigned to each cluster.
          """
          tasklogger.log_start("landmark operator")
          is_sparse = sparse.issparse(self.kernel)
          # spectral clustering
          tasklogger.log_start("SVD")
          _, _, VT = randomized_svd(self.diff_aff,
                                    n_components=self.n_svd,
                                    random_state=self.random_state)
          tasklogger.log_complete("SVD")
          tasklogger.log_start("KMeans")
          kmeans = MiniBatchKMeans(
              self.n_landmark,
              init_size=3 * self.n_landmark,
              batch_size=10000,
              random_state=self.random_state)
          self._clusters = kmeans.fit_predict(
              self.diff_op.dot(VT.T))
          # some clusters are not assigned
          tasklogger.log_complete("KMeans")
  
          # transition matrices
          pmn = self._landmarks_to_data()
  
          # row normalize
          pnm = pmn.transpose()
          pmn = normalize(pmn, norm='l1', axis=1)
          pnm = normalize(pnm, norm='l1', axis=1)
          landmark_op = pmn.dot(pnm)  # sparsity agnostic matrix multiplication
          if is_sparse:
              # no need to have a sparse landmark operator
              landmark_op = landmark_op.toarray()
          # store output
          self._landmark_op = landmark_op
          self._transitions = pnm
          tasklogger.log_complete("landmark operator")