@@ -178,13 +178,15 @@ def eigh(self, matrix: Tensor) -> Tuple[Tensor, Tensor]:
178178
179179 def eigs (self ,
180180 A : Callable ,
181+ args : Optional [List ] = None ,
181182 initial_state : Optional [Tensor ] = None ,
182- num_krylov_vecs : Optional [int ] = 200 ,
183- numeig : Optional [int ] = 6 ,
184- tol : Optional [float ] = 1E-8 ,
185- which : Optional [Text ] = 'LR' ,
186- maxiter : Optional [int ] = None ,
187- dtype : Optional [Type [np .number ]] = None ) -> Tuple [List , List ]:
183+ shape : Optional [Tuple [int , ...]] = None ,
184+ dtype : Optional [Type [np .number ]] = None ,
185+ num_krylov_vecs : int = 50 ,
186+ numeig : int = 6 ,
187+ tol : float = 1E-8 ,
188+ which : Text = 'LR' ,
189+ maxiter : Optional [int ] = None ) -> Tuple [List , List ]:
188190 """
189191 Arnoldi method for finding the lowest eigenvector-eigenvalue pairs
190192 of a linear operator `A`. `A` can be either a
@@ -196,9 +198,14 @@ def eigs(self,
196198
197199 Args:
198200 A: A (sparse) implementation of a linear operator
199- initial_state: An initial vector for the Lanczos algorithm. If `None`,
201+ args: A list of arguments to `A`. `A` will be called as
202+ `res = A(initial_state, *args)`.
203+ initial_state: An initial vector for the algorithm. If `None`,
200204 a random initial `Tensor` is created using the `numpy.random.randn`
201205 method.
206+ shape: The shape of the input-dimension of `A`.
207+ dtype: The dtype of the input `A`. If both no `initial_state` is provided,
208+ a random initial state with shape `shape` and dtype `dtype` is created.
202209 num_krylov_vecs: The number of iterations (number of krylov vectors).
203210 numeig: The nummber of eigenvector-eigenvalue pairs to be computed.
204211 If `numeig > 1`, `reorthogonalize` has to be `True`.
@@ -217,38 +224,37 @@ def eigs(self,
217224 `np.ndarray`: An array of `numeig` lowest eigenvalues
218225 `np.ndarray`: An array of `numeig` lowest eigenvectors
219226 """
227+ if args is None :
228+ args = []
220229 if which == 'SI' :
221230 raise ValueError ('which = SI is currently not supported.' )
222231 if which == 'LI' :
223232 raise ValueError ('which = LI is currently not supported.' )
224233
225- if (initial_state is not None ) and hasattr (A , 'shape' ):
226- if initial_state .shape != A .shape [1 ]:
227- raise ValueError (
228- "A.shape[1]={} and initial_state.shape={} are incompatible." .format (
229- A .shape [1 ], initial_state .shape ))
234+ if numeig + 1 >= num_krylov_vecs :
235+ raise ValueError ('`num_krylov_vecs` > `numeig + 1` required!' )
230236
231237 if initial_state is None :
232- if not hasattr (A , 'shape' ):
233- raise AttributeError ("`A` has no attribute `shape`. Cannot initialize "
234- "lanczos. Please provide a valid `initial_state`" )
235- if not hasattr (A , 'dtype' ):
236- raise AttributeError (
237- "`A` has no attribute `dtype`. Cannot initialize "
238- "lanczos. Please provide a valid `initial_state` with "
239- "a `dtype` attribute" )
240-
241- initial_state = self .randn (A .shape [1 ], A .dtype )
238+ if (shape is None ) or (dtype is None ):
239+ raise ValueError ("if no `initial_state` is passed, then `shape` and"
240+ "`dtype` have to be provided" )
241+ initial_state = self .randn (shape , dtype )
242242
243243 if not isinstance (initial_state , np .ndarray ):
244- raise TypeError ("Expected a `np.array `. Got {}" .format (
244+ raise TypeError ("Expected a `np.ndarray `. Got {}" .format (
245245 type (initial_state )))
246+
247+ shape = initial_state .shape
248+
249+ def matvec (vector ):
250+ return np .ravel (A (np .reshape (vector , shape ), * args ))
251+
246252 #initial_state is an np.ndarray of rank 1, so we can
247253 #savely deduce the shape from it
248254 lop = sp .sparse .linalg .LinearOperator (
249255 dtype = initial_state .dtype ,
250- shape = (initial_state .shape [ 0 ], initial_state .shape [ 0 ] ),
251- matvec = A )
256+ shape = (np . prod ( initial_state .shape ), np . prod ( initial_state .shape ) ),
257+ matvec = matvec )
252258 eta , U = sp .sparse .linalg .eigs (
253259 A = lop ,
254260 k = numeig ,
@@ -260,11 +266,11 @@ def eigs(self,
260266 if dtype :
261267 eta = eta .astype (dtype )
262268 U = U .astype (dtype )
263- return list (eta ), [U [:, n ] for n in range (numeig )]
269+ return list (eta ), [np . reshape ( U [:, n ], shape ) for n in range (numeig )]
264270
265271 def eigsh_lanczos (self ,
266272 A : Callable ,
267- args : List ,
273+ args : Optional [ List [ Tensor ]] = None ,
268274 initial_state : Optional [Tensor ] = None ,
269275 shape : Optional [Tuple ] = None ,
270276 dtype : Optional [Type [np .number ]] = None ,
@@ -309,6 +315,9 @@ def eigsh_lanczos(self,
309315 eigvals: A list of `numeig` lowest eigenvalues
310316 eigvecs: A list of `numeig` lowest eigenvectors
311317 """
318+ if args is None :
319+ args = []
320+
312321 if num_krylov_vecs < numeig :
313322 raise ValueError ('`num_krylov_vecs` >= `numeig` required!' )
314323
0 commit comments