Skip to content

Commit 6179eb9

Browse files
Tao ChenTao Chen
authored andcommitted
add fast QL(incomplete)
1 parent b839474 commit 6179eb9

File tree

1 file changed

+109
-0
lines changed

1 file changed

+109
-0
lines changed

test/explore_QL.jl

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
using PiecewiseOrthogonalPolynomials, Plots, BlockArrays
2+
using MatrixFactorizations, LinearAlgebra, BlockBandedMatrices
3+
###
4+
# QL
5+
####
6+
function my_ql(A::BBBArrowheadMatrix{T}) where T
7+
m,n = size(A.A)
8+
l = length(A.D)
9+
m2, n2 = size(A.D[1])
10+
@assert m == n == l+1
11+
@assert m2 == n2
12+
#results stored in F and tau
13+
F = BlockedArray(Matrix(A), axes(A))
14+
tau = zeros(m+l*m2)
15+
for j in m2:-1:3
16+
for i in l:-1:1
17+
upper_entry = F[Block(j-1, j+1)][i, i] #A.D[i][j-2,j]
18+
dia_entry = F[Block(j+1, j+1)][i, i] #A.D[i][j,j]
19+
#perform Householder transformation
20+
dia_entry_new = -sign(dia_entry)*sqrt(dia_entry^2 + upper_entry^2)
21+
v = [upper_entry, dia_entry-dia_entry_new]
22+
coef = 2/(v[1]^2+v[2]^2)
23+
#denote the householder transformation as [c1 s1;c2 s2]
24+
c1 = 1 - coef * v[1]^2
25+
s1 = - coef * v[1] * v[2]
26+
c2 = s1
27+
s2 = 1 - coef * v[2]^2
28+
print(dia_entry_new)
29+
F[m+(j-1)*l+i, m+(j-1)*l+i] = dia_entry_new #update F[Block(j+1, j+1)][i, i]
30+
F[m+(j-3)*l+i, m+(j-1)*l+i] = v[1]/v[2] #update F[Block(j-1, j+1)][i, i]
31+
tau[m+(j-1)*l+i] = coef*v[2]^2
32+
#row recombination(householder transformation) for other columns
33+
current_upper_entry = F[Block(j-1, j-1)][i, i] #A.D[i][j-2,j-2]
34+
current_lower_entry = F[Block(j+1, j-1)][i, i] #A.D[i][j,j-2]
35+
F[m+(j-3)*l+i, m+(j-3)*l+i] = c1 * current_upper_entry + s1 * current_lower_entry #update F[Block(j-1, j-1)][i, i]
36+
F[m+(j-1)*l+i, m+(j-3)*l+i] = c2 * current_upper_entry + s2 * current_lower_entry #update F[Block(j+1, j-1)][i, i]
37+
if j >= 5
38+
#Deal with A.D blocks which do not share common rows with A.C
39+
current_entry = F[Block(j-1, j-3)][i, i] #A.D[i][j-2,j-4]
40+
F[m+(j-3)*l+i, m+(j-5)*l+i] = c1 * current_entry #update F[Block(j-1, j-3)][i, i]
41+
F[m+(j-1)*l+i, m+(j-5)*l+i] = c2 * current_entry #update F[Block(j+1, j-3)][i, i]
42+
else
43+
#Deal with A.D blocks which share common rows with A.C
44+
current_entry = F[Block(j-1, 1)][i, i] #A.C[j-2][i,i]
45+
F[m+(j-3)*l+i, i] = c1 * current_entry #update F[Block(j-1, 1)][i, i]
46+
F[m+(j-1)*l+i, i] = c2 * current_entry #update F[Block(j+1, 1)][i, i]
47+
48+
current_entry = F[Block(j-1, 1)][i, i+1] #A.C[j-2][i,i+1]
49+
F[m+(j-3)*l+i, i+1] = c1 * current_entry #update F[Block(j-1, 1)][i, i+1]
50+
F[m+(j-1)*l+i, i+1] = c2 * current_entry #F[Block(j+1, 1)][i, i+1]
51+
end
52+
end
53+
end
54+
55+
#Deal with Block(1,3)
56+
#vectors x and Lambda denote a rank 1 semiseperable matrix
57+
lambda = 1.0
58+
Lambda = []
59+
x = [F[Block(1,3)][l+1,l]]
60+
x_len = abs(x[1])
61+
for i in l:-1:2 #consider i=1 later
62+
a = F[Block(1,3)][i,i]
63+
b = F[Block(1,3)][i,i-1]
64+
c = F[Block(3,3)][i,i]
65+
v_last = c + sign(c) * sqrt(a^2 + lambda^2 * x_len^2 + c^2)
66+
v_len = sqrt(a^2 + lambda^2 * x_len^2 + v_last^2)
67+
F[m+l+i,m+l+i] = -sign(c) * sqrt(a^2 + lambda^2 * x_len^2 + c^2)
68+
pushfirst!(Lambda, lambda / v_last)
69+
lambda = -2/v_len^2 * a * b * lambda
70+
F[m+l+i, m+l+i-1] = -2/v_len^2 * v_last * a * b
71+
x_first = (1 - 2/v_len^2 * a^2) * b / lambda
72+
pushfirst!(x, x_first)
73+
x_len = sqrt(x_len^2 + x_first^2)
74+
#record information of V
75+
F[i+1, m+l+i] = 0
76+
F[i, m+l+i] = a / v_last
77+
tau[m+l+i] = 2 * v_last^2 / v_len^2
78+
end
79+
#deal with the last column in Block(1,3)
80+
a = F[Block(1,3)][1,1]
81+
c = F[Block(3,3)][1,1]
82+
v_last = c + sign(c) * sqrt(a^2 + lambda^2 * x_len^2 + c^2)
83+
v_len = sqrt(a^2 + lambda^2 * x_len^2 + v_last^2)
84+
pushfirst!(Lambda, lambda / v_last)
85+
F[m+l+1,m+l+1] = -sign(c) * sqrt(a^2 + lambda^2 * x_len^2 + c^2)
86+
F[2, m+l+1] = 0
87+
F[1, m+l+1] = a / v_last
88+
tau[m+l+1] = 2 * v_last^2 / v_len^2
89+
90+
F, tau, x, Lambda
91+
end
92+
93+
94+
𝐗 = range(-1,1; length=10)
95+
C = ContinuousPolynomial{1}(𝐗)
96+
plot(C[:,Block(2)])
97+
98+
#plot(C[:,Block.(2:3)])
99+
M = C'C
100+
#M = grammatrix(C)
101+
Δ = weaklaplacian(C)
102+
N = 6
103+
KR = Block.(Base.OneTo(N))
104+
Mₙ = M[KR,KR]
105+
Δₙ = Δ[KR,KR]
106+
A = Δₙ + 100^2 * Mₙ
107+
FF,ttau, xx, LLambda = my_ql(A)
108+
#tau = ql(A).τ
109+
#f = ql(A).factors

0 commit comments

Comments
 (0)