blob: 98775018cc2f16d2f44064b925de3aa6c101a724 [file]
// SPDX-FileCopyrightText: The Eigen Authors
// SPDX-License-Identifier: MPL-2.0
// A Koster-Slater impurity: a tight-binding ring of N sites with hopping t and
// one site shifted by V < 0. In the Bloch basis the band is diagonal,
// e_k = -2t cos(2 pi k / N), and the impurity is the rank-one update
// V z z^T with z_k = 1/sqrt(N), so H = D + V z z^T is diagonal plus rank one.
// DPR1EigenSolver finds all N eigenvalues in O(N^2) from the secular equation;
// one of them splits off below the band, approaching the infinite-chain bound
// state -sqrt(V^2 + 4 t^2).
#include <contrib/Eigen/StructuredMatrices>
#include <cmath>
#include <iomanip>
#include <iostream>
using namespace Eigen;
int main() {
const double pi = std::acos(-1.0), t = 1.0, V = -1.5;
std::cout << " N lowest eigenvalue band bottom\n";
for (int N : {16, 64, 256, 1024}) {
VectorXd d(N);
for (int k = 0; k < N; ++k) d[k] = -2 * t * std::cos(2 * pi * k / N);
const VectorXd z = VectorXd::Constant(N, 1 / std::sqrt(double(N)));
const DPR1EigenSolver<double> es(d, V, z, /*options=*/0);
std::cout << std::setw(6) << N << " " << std::setw(16) << es.eigenvalues()[0] << " " << d.minCoeff() << "\n";
}
std::cout << "infinite chain: " << -std::sqrt(V * V + 4 * t * t) << "\n";
}