57template <uni20::LapackRealOrComplex Scalar>
68 if (
abs(
static_cast<Real>(uni20::imag(
value))) > tolerance)
69 throw std::runtime_error(
"DMRG Lanczos received a non-real projected diagonal");
74template <uni20::Real Real>
auto dmrg_lanczos_breakdown(Real
beta, Real alpha, Real previous_beta) ->
bool
81template <uni20::LapackRealOrComplex Scalar,
class Vector,
class Ops>
89 ops.scal(vector,
static_cast<Scalar
>(reciprocal));
95 ops.scal(vector,
static_cast<Scalar
>(maximum));
96 Real const lifted_norm = krylov::norm_or_inner_product<Scalar>(ops, vector);
98 throw std::runtime_error(
"DMRG Lanczos could not normalize a finite nonzero vector");
99 ops.scal(vector, Scalar{1} /
static_cast<Scalar
>(lifted_norm));
120template <uni20::LapackRealOrComplex Scalar,
class Vector, krylov::KrylovMatrixFreeOperator<Vector, Scalar> Ops>
128 if (options.matvec_iterations == 0)
129 throw std::invalid_argument(
"DMRG Lanczos requires at least one matvec iteration");
131 std::size_t
const basis_limit = std::min(problem_dimension, options.matvec_iterations);
133 std::vector<Vector> basis;
134 std::vector<Real> diagonal;
135 std::vector<Real> subdiagonal;
136 basis.reserve(basis_limit);
137 diagonal.reserve(basis_limit);
138 subdiagonal.reserve(basis_limit - 1);
140 Vector start = ops.allocate_like(initial);
141 ops.copy(start, initial);
142 Real const start_norm = krylov::norm_or_inner_product<Scalar>(ops, start);
144 throw std::invalid_argument(
"DMRG Lanczos initial vector must have a finite nonzero norm");
145 detail::normalize_dmrg_lanczos_vector<Scalar>(ops, start, start_norm);
146 basis.push_back(std::move(start));
148 Real final_residual_norm{};
149 int matvec_count = 0;
150 for (std::size_t step = 0; step < basis_limit; ++step)
152 Vector residual = ops.allocate_like(basis[step]);
153 ops.matvec(residual, basis[step]);
156 Real const previous_beta = step == 0 ?
Real{} : subdiagonal[step - 1];
157 if (step > 0) ops.axpy(residual, -
static_cast<Scalar
>(previous_beta), basis[step - 1]);
160 if constexpr (
uni20::Complex<Scalar>) projection_scale = krylov::norm_or_inner_product<Scalar>(ops, residual);
162 detail::dmrg_lanczos_projection_scalar<Scalar>(ops.inner_product(basis[step], residual), projection_scale);
163 diagonal.push_back(alpha);
164 ops.axpy(residual, -
static_cast<Scalar
>(alpha), basis[step]);
166 Real const beta = krylov::norm_or_inner_product<Scalar>(ops, residual);
167 if (!
uni20::isfinite(
beta))
throw std::runtime_error(
"DMRG Lanczos produced a non-finite residual norm");
168 final_residual_norm =
beta;
169 if (step + 1 == basis_limit || detail::dmrg_lanczos_breakdown(
beta, alpha, previous_beta))
break;
171 detail::normalize_dmrg_lanczos_vector<Scalar>(ops, residual,
beta);
172 subdiagonal.push_back(
beta);
173 basis.push_back(std::move(residual));
177 Real const final_coefficient = projected.eigenvectors[basis.size() - 1, 0];
179 Vector vector = ops.allocate_like(initial);
180 ops.copy(vector, basis.front());
181 ops.scal(vector,
static_cast<Scalar
>(projected.eigenvectors[0, 0]));
182 for (std::size_t
row = 1;
row < basis.size(); ++
row)
183 ops.axpy(vector,
static_cast<Scalar
>(projected.eigenvectors[
row, 0]), basis[
row]);
185 return {.energy = projected.eigenvalues.front(),
186 .residual_bound = final_residual_norm *
abs(final_coefficient),
187 .vector = std::move(vector),
188 .iteration_count =
static_cast<int>(basis.size()),
189 .matvec_count = matvec_count};
Concept for complex scalar types.
Definition scalar_concepts.hpp:75
Concept for real scalar types (float, double, etc.).
Definition scalar_concepts.hpp:69
Concept for numeric scalar types (integer, real, or complex).
Definition scalar_concepts.hpp:81
locale_t value
Definition data_table.cpp:49
typename make_real< T >::type make_real_t
Alias for the underlying real-valued type of T.
Definition scalar_traits.hpp:168
constexpr T & real(detail::standard_complex< T > &z) noexcept
Provides mutable access to the real component of a uni20::complex value.
Definition math.hpp:173
constexpr bool isfinite(I const &x) noexcept
Returns whether an integer scalar is finite.
Definition math.hpp:121
Scalar math helper utilities.
TridiagonalEigensystem< Scalar > symmetric_tridiagonal_eigensystem(std::vector< Scalar > diagonal, std::vector< Scalar > subdiagonal, bool compute_vectors)
Solve a real symmetric tridiagonal eigensystem through LAPACK sterf or steqr.
Definition dense_subspace.hpp:288
std::size_t validate_matrix_free_dimensions(Ops const &ops, Vector const &vector, char const *context)
Validate that an initial/prototype vector matches the matrix-free problem dimension.
Definition matrix_free.hpp:549
Definition right_first_rabc.hpp:34
auto dmrg_lanczos_ground_state(Ops &ops, Vector const &initial, DmrgLanczosOptions< uni20::make_real_t< Scalar > > const &options={}) -> DmrgLanczosResult< uni20::make_real_t< Scalar >, Vector >
Perform a lightweight fixed-step Lanczos local ground-state update.
Definition dmrg_lanczos.hpp:121
constexpr auto abs(basic_half_int< T > value) -> basic_half_int< T >
Return the absolute value of a half-integer.
Definition half_int.hpp:431
mpreal norm(mpcomplex const &z)
Definition mpcomplex.hpp:494
void scale(Tensor &tensor, Scalar factor)
Multiply every stored numerical block by a scalar in place.
Definition block_tensor_linear.hpp:400
mpreal beta(mpreal const &a, mpreal const &x)
Real Beta function; positive rational/integer pairs retain exact values.
Definition mpreal_special.hpp:164
Project-level numeric limits customization point.
Definition numeric_limits.hpp:16
Numerical policy for one lightweight DMRG local Lanczos solve.
Definition dmrg_lanczos.hpp:32
std::size_t matvec_iterations
Maximum number of effective-Hamiltonian applications per local update.
Definition dmrg_lanczos.hpp:34
Approximate local ground state produced by fixed-step DMRG Lanczos.
Definition dmrg_lanczos.hpp:41
int matvec_count
Number of effective-Hamiltonian applications.
Definition dmrg_lanczos.hpp:51
int iteration_count
Number of completed Lanczos projection steps.
Definition dmrg_lanczos.hpp:49
Vector vector
Smallest Ritz vector reconstructed in the original vector space.
Definition dmrg_lanczos.hpp:47
Real energy
Smallest Ritz value of the final projected problem.
Definition dmrg_lanczos.hpp:43
Real residual_bound
Final three-term-recurrence Ritz residual estimate.
Definition dmrg_lanczos.hpp:45