Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
82 commits
Select commit Hold shift + click to select a range
c734c45
I have remove all tab
yuiyuiui Mar 30, 2025
adbaf1a
remove blocklanczos.md, all tabs and polish codes to be more easy to …
yuiyuiui Mar 31, 2025
7ad9583
review
GiggleLiu Mar 31, 2025
055c154
inner product version
yuiyuiui Apr 3, 2025
29447c7
mutable block lanczos and tests to be added
yuiyuiui Apr 4, 2025
bf0b9fa
save
yuiyuiui Apr 4, 2025
3292f8d
add test for abstract_qr
yuiyuiui Apr 5, 2025
040577d
the last test of block lanczos facorizations to do
yuiyuiui Apr 6, 2025
6156985
format
yuiyuiui Apr 6, 2025
e4c2d64
revise format
yuiyuiui Apr 6, 2025
6ea0000
format revise
yuiyuiui Apr 6, 2025
0a10ca6
save
yuiyuiui Apr 7, 2025
a2febc6
format
yuiyuiui Apr 7, 2025
fbaf863
format
yuiyuiui Apr 7, 2025
d5a4618
revise project.toml
yuiyuiui Apr 7, 2025
ac130a2
I am ready
yuiyuiui Apr 7, 2025
bb7ea72
firmat
yuiyuiui Apr 8, 2025
a9f0d13
add interface for single vector (element in an abstract inner produnc…
yuiyuiui Apr 11, 2025
72d7dbd
revise Project.toml
yuiyuiui Apr 11, 2025
706f7c8
add references
yuiyuiui Apr 13, 2025
5755e92
revise reference
yuiyuiui Apr 14, 2025
2c0320e
update
yuiyuiui Apr 18, 2025
696aa68
update
yuiyuiui Apr 18, 2025
aa7da7a
to add restart
yuiyuiui Apr 19, 2025
61bfa13
to revise test for block lanczos with shrink
yuiyuiui Apr 19, 2025
b3f2c89
update
yuiyuiui Apr 20, 2025
124b6f2
update
yuiyuiui Apr 20, 2025
7e98d85
save
yuiyuiui Apr 20, 2025
b8f2f0f
add shrink
yuiyuiui Apr 23, 2025
29da1e7
add shrink
yuiyuiui Apr 23, 2025
ba12f42
uodate
yuiyuiui Apr 24, 2025
52d0f6c
update
yuiyuiui Apr 27, 2025
2885493
save
yuiyuiui Apr 27, 2025
07c2f03
eager to add
yuiyuiui Apr 28, 2025
693edc3
add test for eager
yuiyuiui Apr 28, 2025
6ddd467
when blocksize = 1, the efficiency of lanczos and block lanczos is al…
yuiyuiui Apr 29, 2025
83e9b9f
revise what review mentions and add annotation
yuiyuiui Apr 29, 2025
4cf09ae
Added some comments, modified the parameters of , and formatted the f…
yuiyuiui Apr 30, 2025
41d3a24
save
yuiyuiui Apr 30, 2025
3611d5b
Blcok lanczos runs with :inplace
yuiyuiui Apr 30, 2025
0aa7eb1
run for :inplace and all origin tests pass. Now revise tests
yuiyuiui Apr 30, 2025
040b648
I have changed my code to keep the same style with original Lanczos m…
yuiyuiui May 1, 2025
c7196b9
test document
yuiyuiui May 3, 2025
d6abcf6
test document
yuiyuiui May 3, 2025
b3e5c87
test document
yuiyuiui May 3, 2025
082e34b
test document
yuiyuiui May 3, 2025
18c5ad0
add explanation of BlockLanczos lockLanczosFactorization and BlockLan…
yuiyuiui May 3, 2025
f465f9e
add document
yuiyuiui May 5, 2025
2a89360
add more in document and revise a error in origin document
yuiyuiui May 6, 2025
01fddd9
revise some reference, shrink!() to add
yuiyuiui May 7, 2025
da6f153
revise docstring
yuiyuiui May 7, 2025
dd8f098
fix bug and all tests pass
yuiyuiui May 7, 2025
ddf8d45
some revise according to review suggestion
yuiyuiui May 7, 2025
ddc20cb
some revise according to review suggestions
yuiyuiui May 7, 2025
58ca053
some revise
yuiyuiui May 8, 2025
69a6630
revise of review
yuiyuiui May 9, 2025
86abfeb
format and some revise
yuiyuiui May 9, 2025
8ad491f
revise for review
yuiyuiui May 10, 2025
9557400
format
yuiyuiui May 10, 2025
7f7bdf1
try to pass all tests in github
yuiyuiui May 11, 2025
4653e99
try to pass CI
yuiyuiui May 13, 2025
ed89305
format with the lastest JuliaFormatter
yuiyuiui May 13, 2025
79a7cd8
When the Julia version is lower and multi-threading is used, we will …
yuiyuiui May 13, 2025
a08b2b5
Different from the last commit, we don't ignore any test. We change s…
yuiyuiui May 14, 2025
9b3ce65
All checks have passed
yuiyuiui May 14, 2025
1ee3b71
Update docs/src/man/implementation.md
yuiyuiui May 14, 2025
afb1eb7
revise for review
yuiyuiui May 14, 2025
883ffce
revise for review
yuiyuiui May 16, 2025
52db1aa
revise for review
yuiyuiui May 17, 2025
fb5a49d
revise for review
yuiyuiui May 21, 2025
5daae2e
revise for review
yuiyuiui May 22, 2025
e28f4bc
revise for review
yuiyuiui May 22, 2025
4624426
format
yuiyuiui May 22, 2025
b93ad1a
revise for review
yuiyuiui May 23, 2025
7f44f38
revise for review
yuiyuiui May 23, 2025
69ea50a
revise for review
May 27, 2025
421e188
revise for review
May 27, 2025
ff5f5cb
Rename Block.jl to block.jl
May 27, 2025
e7dfd88
revise for review
May 28, 2025
73f3df8
format
May 28, 2025
e019fb7
remove in docstring
May 30, 2025
392ebc6
revise for review
yuiyuiui Jun 8, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
PackageExtensionCompat = "65ce6f38-6b18-4e1d-a461-8949797d7930"
Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7"
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"
VectorInterface = "409d34a3-91d5-4945-b6ec-7529ddf182d8"

[weakdeps]
Expand All @@ -26,6 +27,7 @@ Logging = "1"
PackageExtensionCompat = "1"
Printf = "1"
Random = "1"
SparseArrays = "1.11.0"
Test = "1"
TestExtras = "0.2,0.3"
VectorInterface = "0.5"
Expand Down
43 changes: 43 additions & 0 deletions docs/src/man/Block_Lanczos.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# General Block Lanczos
$A$ is a Hermitian matrix,
$$A = Q T Q'$$

$T$ is a tridiagonal matrix,
$$T = \begin{pmatrix}
\alpha_1 & \beta_1 \\
\beta_1 & \alpha_2 & \beta_2 \\
& \beta_2 & \ddots & \ddots \\
&& \ddots & \alpha_{n-1} & \beta_{n-1} \\
&&& \beta_{n-1} & \alpha_n
\end{pmatrix}$$

But $\beta \neq 0$ and thus eigenvalues of $T$ are different from each other.

To get multiple eigenvalues, we can use block Lanczos.

$$A = Q T Q', \quad Q = [X_1|..|X_n],\quad \text{size}(X_i) = (p,p)$$

$$T = \begin{pmatrix}
M_1 & B_1'\\
B_1 & M_2 & B_2'\\
& B_2 & \ddots & \ddots \\
&& \ddots & M_{n-1} & B_{n-1}'\\
&&& B_{n-1} & M_n
\end{pmatrix}$$

It's advantage is to get multiple eigenvalues. But it's disadvantage is that it can cause ghost eigenvalues because of the loss of orthogonality of the Lanczos vectors.

So my solution is to make sure each $X_i$ we get is orthogonal to $X_{i_1},..,X_1$:

$$X_i = X_i - Q_{i-1}*(Q_{i-1}'X_i)\\
Q_{i-1} = [X_1|..|X_{i-1}]
$$

I use Modified Schidi's method to force the orthogonality of the basis And use some skills to improve the method and speed up.

# Difference between Block Lanczos and Lanczos in code

1. I don't use inner because it maps a couple of matrix to a scalar.
2. I have add test to make sure Block Lanczos can work for map input
3. I add SaprseArray to do test for sparse matrix input

4 changes: 3 additions & 1 deletion src/algorithms.jl
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ Use `Arnoldi` for non-symmetric or non-Hermitian linear operators.
See also: `factorize`, `eigsolve`, `exponentiate`, `Arnoldi`, `Orthogonalizer`
"""
struct Lanczos{O<:Orthogonalizer,S<:Real} <: KrylovAlgorithm
block_size::Int
orth::O
krylovdim::Int
maxiter::Int
Expand All @@ -116,13 +117,14 @@ struct Lanczos{O<:Orthogonalizer,S<:Real} <: KrylovAlgorithm
verbosity::Int
end
function Lanczos(;
block_size::Int=1,
krylovdim::Int=KrylovDefaults.krylovdim[],
maxiter::Int=KrylovDefaults.maxiter[],
tol::Real=KrylovDefaults.tol[],
orth::Orthogonalizer=KrylovDefaults.orth,
eager::Bool=false,
verbosity::Int=KrylovDefaults.verbosity[])
return Lanczos(orth, krylovdim, maxiter, tol, eager, verbosity)
return Lanczos(block_size, orth, krylovdim, maxiter, tol, eager, verbosity)
end

"""
Expand Down
2 changes: 1 addition & 1 deletion src/apply.jl
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
apply(A::AbstractMatrix, x::AbstractVector) = A * x
apply(A::AbstractMatrix, x::AbstractVecOrMat) = A * x
apply(f, x) = f(x)

function apply(operator, x, α₀, α₁)
Expand Down
103 changes: 103 additions & 0 deletions src/eigsolve/lanczos.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ function eigsolve(A, x₀, howmany::Int, which::Selector, alg::Lanczos;
maxiter=alg.maxiter,
eager=alg.eager,
orth=alg.orth))
if alg.block_size > 1
return block_lanczos_reortho(A, x₀, howmany, which, alg)
end
krylovdim = alg.krylovdim
maxiter = alg.maxiter
if howmany > krylovdim
Expand Down Expand Up @@ -150,3 +153,103 @@ function eigsolve(A, x₀, howmany::Int, which::Selector, alg::Lanczos;
vectors,
ConvergenceInfo(converged, residuals, normresiduals, numiter, numops)
end


function block_lanczos_reortho(A, x₀::AbstractMatrix{S}, howmany::Int, which::Selector, alg::Lanczos) where S
block_size = alg.block_size
maxiter = alg.maxiter
tol = alg.tol
verbosity = alg.verbosity
n = size(x₀, 1)
max_blocks = n ÷ block_size

iter = BlockLanczosIterator(A, x₀, block_size, maxiter, alg.orth)
fact = initialize(iter; verbosity = verbosity)
numops = 2

converge_check = max(1, 100 ÷ block_size)

local values, vectors, residuals, normresiduals, num_converged
converged = false

function _res(fact, A, howmany, tol, block_size)
T = triblockdiag(fact)

D, U = eigen(Hermitian((T+T')/2))

by, rev = eigsort(which)
p = sortperm(D; by = by, rev = rev)
D = D[p]
U = U[:, p]

howmany_actual = min(howmany, length(D))
values = D[1:howmany_actual]

basis_so_far = view(fact.V, :, 1:fact.k*block_size)
vectors = Vector{typeof(fact.V[:, 1])}(undef, howmany_actual)

for i in 1:howmany_actual
vectors[i] = similar(basis_so_far, size(basis_so_far, 1))
mul!(vectors[i], basis_so_far, view(U, :, i))
end

residuals = Vector{typeof(vectors[1])}(undef, howmany_actual)
normresiduals = Vector{Float64}(undef, howmany_actual)

for i in 1:howmany_actual
residuals[i] = apply(A, vectors[i])
axpy!(-values[i], vectors[i], residuals[i]) # residuals[i] -= values[i] * vectors[i]
normresiduals[i] = norm(residuals[i])
end

num_converged = count(nr -> nr <= tol, normresiduals)
return values, vectors, residuals, normresiduals, num_converged
end

for numiter in 2:min(maxiter, max_blocks - 2)
expand!(iter, fact; verbosity = verbosity)
numops += 1

if (numiter % converge_check == 0) || (fact.normR < tol)
values, vectors, residuals, normresiduals, num_converged =
_res(fact, A, howmany, tol, block_size)

if verbosity >= EACHITERATION_LEVEL
@info "Block Lanczos eigsolve in iteration $numiter: $num_converged values converged, normres = $(normres2string(normresiduals[1:min(howmany, length(normresiduals))]))"
end

# This convergence condition refers to https://www.netlib.org/utk/people/JackDongarra/etemplates/node251.html
if num_converged >= howmany || fact.normR < tol
converged = true
break
end
end
end

if !converged
values, vectors, residuals, normresiduals, num_converged =
_res(fact, A, howmany, tol, block_size)
end

if (fact.k * block_size > alg.krylovdim)
@warn "The real Krylov dimension is $(fact.k * block_size), which is larger than the maximum allowed dimension $(alg.krylovdim)."
# In this version we don't shrink the factorization because it might cause issues, different from the ordinary Lanczos.
# Why it happens remains to be investigated.
end

if (num_converged < howmany) && verbosity >= WARN_LEVEL
@warn """Block Lanczos eigsolve stopped without full convergence after $(fact.k) iterations:
* $num_converged eigenvalues converged
* norm of residuals = $(normres2string(normresiduals))
* number of operations = $numops"""
elseif verbosity >= STARTSTOP_LEVEL
@info """Block Lanczos eigsolve finished after $(fact.k) iterations:
* $num_converged eigenvalues converged
* norm of residuals = $(normres2string(normresiduals))
* number of operations = $numops"""
end

return values,
vectors,
ConvergenceInfo(num_converged, residuals, normresiduals, fact.k, numops)
end
Loading