Obtain the range of the eigenvalues of a Hermitian operator.
This function provides an estimate of the difference between the
highest and the lowest eigenvalues of the operator. You can adjust its
precision by modifying its default parameters.
- Parameters
operator (np.ndarray or scipy.sparse.spmatrix or Tensor) – The Hermitian operator \(M\) whose range of eigenvalues you
want to determine.
iteration_count (int, optional) – The number of iterations \(N\) in the calculation. Defaults to
3000. Choose a higher number to improve the precision, or a smaller
number to make the estimation run faster.
seed (int, optional) – The random seed that the function uses to choose the initial random
vector \(\left| r \right\rangle\). Defaults to None, which
means that the function uses a different seed in each run.
name (str, optional) – The name of the node.
- Returns
The difference between the largest and the smallest eigenvalues of
the operator.
- Return type
Tensor (scalar, real)
Warning
This calculation can be expensive, so we recommend that you run it
before the optimization, if possible. You can do this by using a
representative or a worst-case operator.
Notes
This function repeatedly multiplies the operator \(M\) with a
random vector \(\left| r \right\rangle\). In terms of the operator’s
eigenvalues \(\{ v_i \}\) and eigenvectors
\(\{\left|v_i \right\rangle\}\), the result of \(N\) matrix
multiplications is:
\[M^N \left|r\right\rangle = \sum_i v_i^N \left|v_i\right\rangle
\left\langle v_i \right. \left| r \right\rangle.\]
For large \(N\), the term corresponding to the eigenvalue with
largest absolute value \(V\) will dominate the sum, as long as
\(\left|r\right\rangle\) has a non-zero overlap with its
eigenvector. The function then retrieves the eigenvalue \(V\) via:
\[V \approx \frac{\left\langle r \right| M^{2N+1} \left| r
\right\rangle}{\left\| M^N \left| r \right\rangle \right\|^2}.\]
The same procedure applied to the matrix \(M-V\) allows the function
to find the eigenvalue at the opposite end of the spectral range.
Examples
>>> operator = np.diag([10, 40])
>>> graph.spectral_range(operator, name="spectral_range")
<Tensor: name="spectral_range", operation_name="spectral_range", shape=()>
>>> result = qctrl.functions.calculate_graph(
... graph=graph, output_node_names=["spectral_range"]
... )
>>> result.output["spectral_range"]["value"]
30.0
See more examples in the How to optimize controls on large sparse Hamiltonians user guide.