Perform targeted eigenmode search using the scipy/ARPACK sparse solver for the reformulated generalized eigenvalue problem A.x = λ B.x ==> (A - σB)^I B.x = (1/(λ-σ)) x for eigenvalues λ near the target σ. Parameters ---------- A, B : scipy sparse matrices
(A, B, left, N, target, matsolver, **kw)
| 396 | |
| 397 | |
| 398 | def scipy_sparse_eigs(A, B, left, N, target, matsolver, **kw): |
| 399 | """ |
| 400 | Perform targeted eigenmode search using the scipy/ARPACK sparse solver |
| 401 | for the reformulated generalized eigenvalue problem |
| 402 | |
| 403 | A.x = λ B.x ==> (A - σB)^I B.x = (1/(λ-σ)) x |
| 404 | |
| 405 | for eigenvalues λ near the target σ. |
| 406 | |
| 407 | Parameters |
| 408 | ---------- |
| 409 | A, B : scipy sparse matrices |
| 410 | Sparse matrices for generalized eigenvalue problem |
| 411 | N : int |
| 412 | Number of eigenmodes to return |
| 413 | left: boolean |
| 414 | Whether to solve for the left eigenvectors or not |
| 415 | target : complex |
| 416 | Target σ for eigenvalue search |
| 417 | matsolver : matrix solver class |
| 418 | Class implementing solve method for solving sparse systems. |
| 419 | |
| 420 | Other keyword options passed to scipy.sparse.linalg.eigs. |
| 421 | """ |
| 422 | # Build sparse linear operator representing (A - σB)^I B = C^I B = D |
| 423 | C = A - target * B |
| 424 | solver = matsolver(C) |
| 425 | def matvec(x): |
| 426 | return solver.solve(B.dot(x)) |
| 427 | D = spla.LinearOperator(dtype=A.dtype, shape=A.shape, matvec=matvec) |
| 428 | # Solve using scipy sparse algorithm |
| 429 | evals, evecs = spla.eigs(D, k=N, which='LM', sigma=None, **kw) |
| 430 | # Rectify eigenvalues |
| 431 | evals = 1 / evals + target |
| 432 | if left: |
| 433 | # Build sparse linear operator representing (A^H - conj(σ)B^H)^I B^H = C^-H B^H = left_D |
| 434 | # Note: left_D is not equal to D^H |
| 435 | def matvec_left(x): |
| 436 | return solver.solve_H(B.conj().T.dot(x)) |
| 437 | left_D = spla.LinearOperator(dtype=A.dtype, shape=A.shape, matvec=matvec_left) |
| 438 | # Solve using scipy sparse algorithm |
| 439 | left_evals, left_evecs = spla.eigs(left_D, k=N, which='LM', sigma=None, **kw) |
| 440 | # Rectify left eigenvalues |
| 441 | left_evals = 1 / left_evals + np.conj(target) |
| 442 | return evals, evecs, left_evals, left_evecs |
| 443 | else: |
| 444 | return evals, evecs |
| 445 | |
| 446 | |
| 447 | def interleave_matrices(matrices): |