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
The ER stand for explicitly restarted. The Lanczos method used is based on this reference which can reproduce the degenerate correctly.
The Lanczos solver only works for symmetric/Hermitian operators.
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.