enable multiple vector rayleigh_quotient_iteration
This commit is contained in:
parent
3b57619c2f
commit
f0ef31c25d
@ -34,7 +34,7 @@ def power_iteration(operator: sparse.spmatrix,
|
|||||||
|
|
||||||
|
|
||||||
def rayleigh_quotient_iteration(operator: sparse.spmatrix or spalg.LinearOperator,
|
def rayleigh_quotient_iteration(operator: sparse.spmatrix or spalg.LinearOperator,
|
||||||
guess_vector: numpy.ndarray,
|
guess_vectors: numpy.ndarray,
|
||||||
iterations: int = 40,
|
iterations: int = 40,
|
||||||
tolerance: float = 1e-13,
|
tolerance: float = 1e-13,
|
||||||
solver=None,
|
solver=None,
|
||||||
@ -42,15 +42,21 @@ def rayleigh_quotient_iteration(operator: sparse.spmatrix or spalg.LinearOperato
|
|||||||
"""
|
"""
|
||||||
Use Rayleigh quotient iteration to refine an eigenvector guess.
|
Use Rayleigh quotient iteration to refine an eigenvector guess.
|
||||||
|
|
||||||
:param operator: Matrix to analyze.
|
TODO:
|
||||||
:param guess_vector: Eigenvector to refine.
|
Need to test this for more than one guess_vectors.
|
||||||
:param iterations: Maximum number of iterations to perform. Default 40.
|
|
||||||
:param tolerance: Stop iteration if (A - I*eigenvalue) @ v < tolerance.
|
Args:
|
||||||
Default 1e-13.
|
operator: Matrix to analyze.
|
||||||
:param solver: Solver function of the form x = solver(A, b).
|
guess_vectors: Eigenvectors to refine.
|
||||||
By default, use scipy.sparse.spsolve for sparse matrices and
|
iterations: Maximum number of iterations to perform. Default 40.
|
||||||
scipy.sparse.bicgstab for general LinearOperator instances.
|
tolerance: Stop iteration if `(A - I*eigenvalue) @ v < num_vectors * tolerance`,
|
||||||
:return: (eigenvalue, eigenvector)
|
Default 1e-13.
|
||||||
|
solver: Solver function of the form `x = solver(A, b)`.
|
||||||
|
By default, use scipy.sparse.spsolve for sparse matrices and
|
||||||
|
scipy.sparse.bicgstab for general LinearOperator instances.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
(eigenvalues, eigenvectors)
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
_test = operator - sparse.eye(operator.shape[0])
|
_test = operator - sparse.eye(operator.shape[0])
|
||||||
@ -64,16 +70,16 @@ def rayleigh_quotient_iteration(operator: sparse.spmatrix or spalg.LinearOperato
|
|||||||
if solver is None:
|
if solver is None:
|
||||||
solver = lambda A, b: spalg.bicgstab(A, b)[0]
|
solver = lambda A, b: spalg.bicgstab(A, b)[0]
|
||||||
|
|
||||||
v = guess_vector
|
v = numpy.atleast_2d(guess_vectors)
|
||||||
v /= norm(v)
|
v /= norm(v)
|
||||||
for _ in range(iterations):
|
for _ in range(iterations):
|
||||||
eigval = v.conj() @ (operator @ v)
|
eigval = v.conj() @ (operator @ v)
|
||||||
if norm(operator @ v - eigval * v) < tolerance:
|
if norm(operator @ v - eigval * v) < v.shape[1] * tolerance:
|
||||||
break
|
break
|
||||||
|
|
||||||
shifted_operator = operator - shift(eigval)
|
shifted_operator = operator - shift(eigval)
|
||||||
v = solver(shifted_operator, v)
|
v = solver(shifted_operator, v)
|
||||||
v /= norm(v)
|
v /= norm(v, axis=0)
|
||||||
return eigval, v
|
return eigval, v
|
||||||
|
|
||||||
|
|
||||||
@ -99,7 +105,7 @@ def signed_eigensolve(operator: sparse.spmatrix or spalg.LinearOperator,
|
|||||||
Shift by the absolute value of the largest eigenvalue, then find a few of the
|
Shift by the absolute value of the largest eigenvalue, then find a few of the
|
||||||
largest-magnitude (shifted) eigenvalues. A positive shift ensures that we find the
|
largest-magnitude (shifted) eigenvalues. A positive shift ensures that we find the
|
||||||
largest _positive_ eigenvalues, since any negative eigenvalues will be shifted to the
|
largest _positive_ eigenvalues, since any negative eigenvalues will be shifted to the
|
||||||
range 0 >= neg_eigval + abs(lm_eigval) > abs(lm_eigval)
|
range `0 >= neg_eigval + abs(lm_eigval) > abs(lm_eigval)`
|
||||||
'''
|
'''
|
||||||
shift = numpy.abs(lm_eigval)
|
shift = numpy.abs(lm_eigval)
|
||||||
if negative:
|
if negative:
|
||||||
|
Loading…
Reference in New Issue
Block a user