docs: def fit(self, vecs, iter=20, seed=123):
          """Given training vectors, run k-means for each sub-space and create
          codewords for each sub-space.
  
          This function should be run once first of all.
  
          Args:
              vecs (np.ndarray): Training vectors with shape=(N, D) and dtype=np.float32.
              iter (int): The number of iteration for k-means
              seed (int): The seed for random process
  
          Returns:
              object: self
  
          """
          assert vecs.dtype == np.float32
          assert vecs.ndim == 2
          N, D = vecs.shape
          assert self.Ks < N, "the number of training vector should be more than Ks"
          assert D % self.M == 0, "input dimension must be dividable by M"
          self.Ds = int(D / self.M)
  
          np.random.seed(seed)
          if self.verbose:
              print("iter: {}, seed: {}".format(iter, seed))
  
          # [m][ks][ds]: m-th subspace, ks-the codeword, ds-th dim
          self.codewords = np.zeros((self.M, self.Ks, self.Ds), dtype=np.float32)
          for m in range(self.M):
              if self.verbose:
                  print("Training the subspace: {} / {}".format(m, self.M))
              vecs_sub = vecs[:, m * self.Ds : (m+1) * self.Ds]
              self.codewords[m], _ = kmeans2(vecs_sub, self.Ks, iter=iter, minit='points')
  
          return self