docs: def decode(self, codes):
          """Given PQ-codes, reconstruct original D-dimensional vectors
          approximately by fetching the codewords.
  
          Args:
              codes (np.ndarray): PQ-cdoes with shape=(N, M) and dtype=self.code_dtype.
                  Each row is a PQ-code
  
          Returns:
              np.ndarray: Reconstructed vectors with shape=(N, D) and dtype=np.float32
  
          """
          assert codes.ndim == 2
          N, M = codes.shape
          assert M == self.M
          assert codes.dtype == self.code_dtype
  
          vecs = np.empty((N, self.Ds * self.M), dtype=np.float32)
          for m in range(self.M):
              vecs[:, m * self.Ds : (m+1) * self.Ds] = self.codewords[m][codes[:, m], :]
  
          return vecs