class_docstr: Spectral Co-Clustering algorithm (Dhillon, 2001).
  
  Clusters rows and columns of an array `X` to solve the relaxed
  normalized cut of the bipartite graph created from `X` as follows:
  the edge between row vertex `i` and column vertex `j` has weight
  `X[i, j]`.
  
  The resulting bicluster structure is block-diagonal, since each
  row and each column belongs to exactly one bicluster.
  
  Supports sparse matrices, as long as they are nonnegative.
  
  Read more in the :ref:`User Guide <spectral_coclustering>`.
  
  Parameters
  ----------
  n_clusters : int, default=3
      The number of biclusters to find.
  
  svd_method : {'randomized', 'arpack'}, default='randomized'
      Selects the algorithm for finding singular vectors. May be
      'randomized' or 'arpack'. If 'randomized', use
      :func:`sklearn.utils.extmath.randomized_svd`, which may be faster
      for large matrices. If 'arpack', use
      :func:`scipy.sparse.linalg.svds`, which is more accurate, but
      possibly slower in some cases.
  
  n_svd_vecs : int, default=None
      Number of vectors to use in calculating the SVD. Corresponds
      to `ncv` when `svd_method=arpack` and `n_oversamples` when
      `svd_method` is 'randomized`.
  
  mini_batch : bool, default=False
      Whether to use mini-batch k-means, which is faster but may get
      different results.
  
  init : {'k-means++', 'random'}, or ndarray of shape             (n_clusters, n_features), default='k-means++'
      Method for initialization of k-means algorithm; defaults to
      'k-means++'.
  
  n_init : int, default=10
      Number of random initializations that are tried with the
      k-means algorithm.
  
      If mini-batch k-means is used, the best initialization is
      chosen and the algorithm runs once. Otherwise, the algorithm
      is run for each initialization and the best solution chosen.
  
  random_state : int, RandomState instance, default=None
      Used for randomizing the singular value decomposition and the k-means
      initialization. Use an int to make the randomness deterministic.
      See :term:`Glossary <random_state>`.
  
  Attributes
  ----------
  rows_ : array-like of shape (n_row_clusters, n_rows)
      Results of the clustering. `rows[i, r]` is True if
      cluster `i` contains row `r`. Available only after calling ``fit``.
  
  columns_ : array-like of shape (n_column_clusters, n_columns)
      Results of the clustering, like `rows`.
  
  row_labels_ : array-like of shape (n_rows,)
      The bicluster label of each row.
  
  column_labels_ : array-like of shape (n_cols,)
      The bicluster label of each column.
  
  biclusters_ : tuple of two ndarrays
      The tuple contains the `rows_` and `columns_` arrays.
  
  n_features_in_ : int
      Number of features seen during :term:`fit`.
  
      .. versionadded:: 0.24
  
  feature_names_in_ : ndarray of shape (`n_features_in_`,)
      Names of features seen during :term:`fit`. Defined only when `X`
      has feature names that are all strings.
  
      .. versionadded:: 1.0
  
  See Also
  --------
  SpectralBiclustering : Partitions rows and columns under the assumption
      that the data has an underlying checkerboard structure.
  
  References
  ----------
  * :doi:`Dhillon, Inderjit S, 2001. Co-clustering documents and words using
    bipartite spectral graph partitioning.
    <10.1145/502512.502550>`
  
  Examples
  --------
  >>> from sklearn.cluster import SpectralCoclustering
  >>> import numpy as np
  >>> X = np.array([[1, 1], [2, 1], [1, 0],
  ...               [4, 7], [3, 5], [3, 6]])
  >>> clustering = SpectralCoclustering(n_clusters=2, random_state=0).fit(X)
  >>> clustering.row_labels_ #doctest: +SKIP
  array([0, 1, 1, 0, 0, 0], dtype=int32)
  >>> clustering.column_labels_ #doctest: +SKIP
  array([0, 0], dtype=int32)
  >>> clustering
  SpectralCoclustering(n_clusters=2, random_state=0)
code: def _fit(self, X):
      normalized_data, row_diag, col_diag = _scale_normalize(X)
      n_sv = 1 + int(np.ceil(np.log2(self.n_clusters)))
      u, v = self._svd(normalized_data, n_sv, n_discard=1)
      z = np.vstack(
          (row_diag[:, np.newaxis] * u, col_diag[:, np.newaxis] * v)
      )
  
      _, labels = self._k_means(z, self.n_clusters)
  
      n_rows = X.shape[0]
      self.row_labels_ = labels[:n_rows]
      self.column_labels_ = labels[n_rows:]
  
      self.rows_ = np.vstack(
          [self.row_labels_ == c for c in range(self.n_clusters)]
      )
      self.columns_ = np.vstack(
          [self.column_labels_ == c for c in range(self.n_clusters)]
      )
  
imports: from abc import ABCMeta, abstractmethod
  from numbers import Integral
  import numpy
  from scipy.linalg import norm
  from scipy.sparse import dia_matrix, issparse
  from scipy.sparse.linalg import eigsh, svds
  from ..base import BaseEstimator, BiclusterMixin, _fit_context
  from ..utils import check_random_state, check_scalar
  from ..utils._param_validation import Interval, StrOptions
  from ..utils.extmath import make_nonnegative, randomized_svd, safe_sparse_dot
  from ..utils.validation import assert_all_finite
  from ._kmeans import KMeans, MiniBatchKMeans
label_desc: Use image node_id 3 for calling the SpectralCoclustering obj's underlying member method code with example usage: obj._fit(X) without return types