10.2. Lanczos solver

In Cytnx, an eigenvalue problem can be solved for a custom linear operator defined using the LinOp class by using the Lanczos iterative solver.

For this, you can pass a LinOp or any of its child classes to linalg.Lanczos_ER:

Lanczos_ER(Hop, k=1, is_V=true, maxiter=10000, CvgCrit=1.0e-14, is_row=false, Tin=Tensor(), max_krydim=4)

Perform Lanczos for hermitian/symmetric matrices or linear function.

Parameters:
  • Hop (LinOp) – the Linear Operator defined by LinOp class or its inheritance.

  • k (uint64) – the number of lowest k eigenvalues

  • is_V (bool) – if set to true, the eigenvectors will be returned

  • maxiter (uint64) – the maximum number of iteration steps for each k

  • CvgCrit (double) – the convergence criterion of the energy

  • is_row (bool) – whether the returned eigenvectors should be in row-major form

  • Tin (Tensor) – the initial vector, should be a Tensor with rank-1

  • max_krydim (uint32) – the maximum Krylov subspace dimension for each iteration

Returns:

[eigvals (Tensor), eigvecs (Tensor)(option)]

Return type:

vector<Tensor> (C++ API)/list of Tensor(python API)

For example, we consider a simple example where we wrap a (4x4) matrix inside a custom operator. We can easily generalize the matvec to be any custom sparse structure.

  • In Python:

 1class MyOp(cytnx.LinOp):
 2  def __init__(self):
 3    cytnx.LinOp.__init__(self,"mv",4)
 4
 5  def matvec(self,v):
 6    A = cytnx.arange(16).reshape(4,4)
 7    A += A.permute(1,0)
 8    return cytnx.linalg.Dot(A,v)
 9
10
11op = MyOp()
12
13v0 = cytnx.arange(4) # trial state
14ev = cytnx.linalg.Lanczos(op, k=1, Tin=v0, method="ER", max_krydim = 2)
15
16print(ev[0]) #eigenval
17print(ev[1]) #eigenvec
  • In C++:

 1using namespace cytnx;
 2class MyOp : public LinOp {
 3 public:
 4  MyOp() : LinOp("mv", 6) {
 5    // Create Hermitian Matrix
 6    A = arange(36).reshape(6, 6);
 7    A += A.permute(1, 0);
 8  }
 9
10 private:
11  Tensor A;
12  Tensor matvec(const Tensor &v) override { return linalg::Dot(A, v); }
13};
14
15auto op = MyOp();
16
17auto v0 = arange(6);  // trial state
18auto ev = linalg::Lanczos_ER(&op, 1, true, 10000, 1.0e-14, false, v0);
19
20cout << ev[0] << endl;  // eigenval
21cout << ev[1] << endl;  // eigenvec

Output >>

Total elem: 1
type  : Double (Float64)
cytnx device: CPU
Shape : (1)
[-7.41657e+00 ]




Total elem: 4
type  : Double (Float64)
cytnx device: CPU
Shape : (4)
[-7.94119e-01 -3.69644e-01 5.48299e-02 4.79304e-01 ]

Note

  1. The ER stand for explicitly restarted. The Lanczos method used is based on this reference which can reproduce the degenerate correctly.

  2. The Lanczos solver only works for symmetric/Hermitian operators.

  3. In cases where the operator is small, try to reduce the max_krydim to get a correct convergence.

See also

The solver is used in the example Exact Diagonalization for the one dimensional transverse field Ising model.