|
| 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