def _spectral_embedding(self, X): """ Helper function to embed the dataset X into the eigenvectors of the graph Laplacian matrix Returns ------- ht.DNDarray, shape=(m_lanczos): Eigenvalues of the graph's Laplacian matrix. ht.DNDarray, shape=(n, m_lanczos): Eigenvectors of the graph's Laplacian matrix. """ L = self._laplacian.construct(X) # 3. Eigenvalue and -vector calculation via Lanczos Algorithm v0 = ht.full( (L.shape[0], ), fill_value=1.0 / math.sqrt(L.shape[0]), dtype=L.dtype, split=0, device=L.device, ) V, T = ht.lanczos(L, self.n_lanczos, v0) # 4. Calculate and Sort Eigenvalues and Eigenvectors of tridiagonal matrix T eval, evec = torch.eig(T._DNDarray__array, eigenvectors=True) # If x is an Eigenvector of T, then y = V@x is the corresponding Eigenvector of L eval, idx = torch.sort(eval[:, 0], dim=0) eigenvalues = ht.array(eval) eigenvectors = ht.matmul(V, ht.array(evec))[:, idx] return eigenvalues, eigenvectors
def _spectral_embedding(self, x: DNDarray) -> Tuple[DNDarray, DNDarray]: """ Helper function for dataset x embedding. Returns Tupel(Eigenvalues, Eigenvectors) of the graph's Laplacian matrix. Parameters ---------- x : DNDarray Sample Matrix for which the embedding should be calculated """ L = self._laplacian.construct(x) # 3. Eigenvalue and -vector calculation via Lanczos Algorithm v0 = ht.full( (L.shape[0],), fill_value=1.0 / math.sqrt(L.shape[0]), dtype=L.dtype, split=0, device=L.device, ) V, T = ht.lanczos(L, self.n_lanczos, v0) # 4. Calculate and Sort Eigenvalues and Eigenvectors of tridiagonal matrix T eval, evec = torch.eig(T.larray, eigenvectors=True) # If x is an Eigenvector of T, then y = V@x is the corresponding Eigenvector of L eval, idx = torch.sort(eval[:, 0], dim=0) eigenvalues = ht.array(eval) eigenvectors = ht.matmul(V, ht.array(evec))[:, idx] return eigenvalues, eigenvectors
def _spectral_embedding(self, x: DNDarray) -> Tuple[DNDarray, DNDarray]: """ Helper function for dataset x embedding. Returns Tupel(Eigenvalues, Eigenvectors) of the graph's Laplacian matrix. Parameters ---------- x : DNDarray Sample Matrix for which the embedding should be calculated Notes ----- This will throw out the complex side of the eigenvalues found during this. """ L = self._laplacian.construct(x) # 3. Eigenvalue and -vector calculation via Lanczos Algorithm v0 = ht.full( (L.shape[0], ), fill_value=1.0 / math.sqrt(L.shape[0]), dtype=L.dtype, split=0, device=L.device, ) V, T = ht.lanczos(L, self.n_lanczos, v0) # if int(torch.__version__.split(".")[1]) >= 9: try: # 4. Calculate and Sort Eigenvalues and Eigenvectors of tridiagonal matrix T eval, evec = torch.linalg.eig(T.larray) # If x is an Eigenvector of T, then y = V@x is the corresponding Eigenvector of L eval, idx = torch.sort(eval.real, dim=0) eigenvalues = ht.array(eval) eigenvectors = ht.matmul(V, ht.array(evec))[:, idx] return eigenvalues.real, eigenvectors.real except AttributeError: # torch version is less than 1.9.0 # 4. Calculate and Sort Eigenvalues and Eigenvectors of tridiagonal matrix T eval, evec = torch.eig(T.larray, eigenvectors=True) # If x is an Eigenvector of T, then y = V@x is the corresponding Eigenvector of L eval, idx = torch.sort(eval[:, 0], dim=0) eigenvalues = ht.array(eval) eigenvectors = ht.matmul(V, ht.array(evec))[:, idx] return eigenvalues, eigenvectors