Perform dense eigenvector search for selected subproblem. This routine finds all eigenvectors but is computationally expensive. Parameters ---------- subproblem : Subproblem object Subproblem for which to solve the EVP. rebuild_matrices :
(self, subproblem, rebuild_matrices=False, left=False, normalize_left=True, **kw)
| 178 | print(f"MPI rank: {self.dist.comm.rank}, subproblem: {i}, group: {sp.group}, matrix rank: {np.linalg.matrix_rank(A)}/{A.shape[0]}, cond: {np.linalg.cond(A):.1e}") |
| 179 | |
| 180 | def solve_dense(self, subproblem, rebuild_matrices=False, left=False, normalize_left=True, **kw): |
| 181 | """ |
| 182 | Perform dense eigenvector search for selected subproblem. |
| 183 | This routine finds all eigenvectors but is computationally expensive. |
| 184 | |
| 185 | Parameters |
| 186 | ---------- |
| 187 | subproblem : Subproblem object |
| 188 | Subproblem for which to solve the EVP. |
| 189 | rebuild_matrices : bool, optional |
| 190 | Rebuild LHS matrices if coefficients have changed (default: False). |
| 191 | left : bool, optional |
| 192 | Solve for the left eigenvectors of the system in addition to the |
| 193 | right eigenvectors. The left eigenvectors are the right eigenvectors |
| 194 | of the conjugate-transposed problem. Follows same definition described |
| 195 | in scipy.linalg.eig documentation (default: False). |
| 196 | normalize_left : bool, optional |
| 197 | Normalize the left eigenvectors such that the modified left eigenvectors |
| 198 | form a biorthonormal (not just biorthogonal) set with respect to the right |
| 199 | eigenvectors (default: True). |
| 200 | **kw : |
| 201 | Other keyword options passed to scipy.linalg.eig. |
| 202 | """ |
| 203 | self.eigenvalue_subproblem = sp = subproblem |
| 204 | # Build matrices if directed or not yet built |
| 205 | if rebuild_matrices or not hasattr(sp, 'L_min'): |
| 206 | self.build_matrices([sp], ['M', 'L']) |
| 207 | # Solve as dense general eigenvalue problem |
| 208 | A = sp.L_min.toarray() |
| 209 | B = - sp.M_min.toarray() |
| 210 | eig_output = scipy.linalg.eig(A, b=B, left=left, **kw) |
| 211 | # Unpack output |
| 212 | if left: |
| 213 | self.eigenvalues, pre_left_evecs, pre_right_evecs = eig_output |
| 214 | self.right_eigenvectors = self.eigenvectors = sp.pre_right @ pre_right_evecs |
| 215 | self.left_eigenvectors = sp.pre_left.conj().T @ pre_left_evecs |
| 216 | self.modified_left_eigenvectors = (sp.M_min @ sp.pre_right_pinv).conj().T @ pre_left_evecs |
| 217 | if normalize_left: |
| 218 | norms = np.diag(pre_left_evecs.T.conj() @ sp.M_min @ pre_right_evecs) |
| 219 | self.left_eigenvectors /= np.conj(norms) |
| 220 | self.modified_left_eigenvectors /= np.conj(norms) |
| 221 | else: |
| 222 | self.eigenvalues, pre_eigenvectors = eig_output |
| 223 | self.eigenvectors = sp.pre_right @ pre_eigenvectors |
| 224 | |
| 225 | def solve_sparse(self, subproblem, N, target, rebuild_matrices=False, left=False, normalize_left=True, raise_on_mismatch=True, v0=None, **kw): |
| 226 | """ |