Skip to content

Commit f88fac8

Browse files
committed
BesselJ example
1 parent f37a603 commit f88fac8

File tree

7 files changed

+127
-24
lines changed

7 files changed

+127
-24
lines changed

Project.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ julia = "1"
2626
[extras]
2727
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
2828
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
29+
SpecialFunctions = "276daf66-3868-5448-9aa4-cd146d93841b"
2930

3031
[targets]
31-
test = ["Test", "Random"]
32+
test = ["Test", "Random", "SpecialFunctions"]

README.md

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,63 @@ A Julia repository for linear algebra with infinite banded and block-banded matr
77

88
This currently supports the infinite-dimensional QR factorization for banded matrices, also known as the adaptive QR decomposition as the entries of the QR decomposition are determined lazily.
99

10+
As a simple example, consider the Bessel recurrence relationship:
11+
$$
12+
J_{n-1}(z) - {2 n \over z} J_n(z) + J_{n+1}(z) = 0
13+
$$
14+
This can be recast as an infinite linear system:
15+
```julia
16+
julia> using InfiniteLinearAlgebra, InfiniteArrays, BandedMatrices, FillArrays, SpecialFunctions
17+
18+
julia> z = 10_000; # the bigger z the longer before we see convergence
19+
20+
julia> A = BandedMatrix(0 => -2*(0:∞)/z, 1 => Ones(∞), -1 => Ones(∞))
21+
×∞ BandedMatrix{Float64,ApplyArray{Float64,2,typeof(*),Tuple{Array{Float64,2},ApplyArray{Float64,2,typeof(vcat),Tuple{Transpose{Float64,InfiniteArrays.InfStepRange{Float64,Float64}},Ones{Float64,2,Tuple{Base.OneTo{Int64},InfiniteArrays.OneToInf{Int64}}},Ones{Float64,2,Tuple{Base.OneTo{Int64},InfiniteArrays.OneToInf{Int64}}}}}}},InfiniteArrays.OneToInf{Int64}} with indices OneToInf()×OneToInf():
22+
0.0 1.0
23+
1.0 -0.0002 1.0
24+
1.0 -0.0004 1.0
25+
1.0 -0.0006 1.0
26+
1.0 -0.0008 1.0
27+
1.0 -0.001 1.0
28+
1.0 -0.0012 1.0
29+
1.0 -0.0014 1.0
30+
1.0 -0.0016
31+
1.0
32+
33+
34+
35+
36+
37+
38+
```
39+
The first row corresponds to specifying an initial condition. Thus we can determine $J_n(z)$ via solving the recurrence:
40+
```julia
41+
julia> A \ Vcat([besselj(1,z)], Zeros(∞))
42+
-element LazyArrays.CachedArray{Float64,1,Array{Float64,1},Zeros{Float64,1,Tuple{InfiniteArrays.OneToInf{Int64}}}} with indices OneToInf():
43+
-0.007096160353406478
44+
0.0036474507555295833
45+
0.007096889843557584
46+
-0.0036446119995921654
47+
-0.007099076610757337
48+
0.0036389327383035616
49+
0.00710271554349564
50+
-0.003630409479651369
51+
-0.007107798116767152
52+
0.0036190370026645442
53+
0.007114312383371949
54+
-0.0036048083778978026
55+
-0.0071222429618033245
56+
0.0035877149947894766
57+
0.007131571020789777
58+
59+
60+
julia> J[1000] - besselj(999,z) # matches besselj to high (relative) accuracy
61+
-6.8252695162307475e-15
62+
63+
julia> J[11_000] - besselj(11_000-1, z)
64+
3.3730094946097293e-143
65+
```
66+
1067
## Infinite-dimensional QL factorization
1168

1269

src/InfiniteLinearAlgebra.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import BandedMatrices: BandedMatrix, _BandedMatrix, bandeddata, bandwidths
1212
import LinearAlgebra: lmul!, ldiv!, matprod, qr, AbstractTriangular, AbstractQ, adjoint, transpose
1313
import LazyArrays: CachedArray, CachedMatrix, CachedVector, DenseColumnMajor, FillLayout, ApplyMatrix, check_mul_axes, ApplyStyle, LazyArrayApplyStyle, LazyArrayStyle,
1414
CachedMatrix, CachedArray, resizedata!, MemoryLayout, mulapplystyle, LmulStyle, RmulStyle,
15-
colsupport, rowsupport, triangularlayout
15+
colsupport, rowsupport, triangularlayout, factorize
1616
import MatrixFactorizations: ql, ql!, QLPackedQ, getL, getR, reflector!, reflectorApply!, QL, QR, QRPackedQ
1717

1818
import BlockArrays: BlockSizes, cumulsizes, _find_block, AbstractBlockVecOrMat, sizes_from_blocks

src/banded/infbanded.jl

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,22 @@ const TriPertToeplitz{T} = Tridiagonal{T,Vcat{T,1,Tuple{Vector{T},Fill{T,1,Tuple
88
const AdjTriPertToeplitz{T} = Adjoint{T,Tridiagonal{T,Vcat{T,1,Tuple{Vector{T},Fill{T,1,Tuple{OneToInf{Int}}}}}}}
99
const InfBandedMatrix{T,V<:AbstractMatrix{T}} = BandedMatrix{T,V,OneToInf{Int}}
1010

11+
function BandedMatrix{T}(kv::Tuple{Vararg{Pair{<:Integer,<:AbstractVector}}},
12+
::NTuple{2,Infinity},
13+
(l,u)::NTuple{2,Integer}) where T
14+
ks = getproperty.(kv, :first)
15+
rws = Vcat(permutedims.(getproperty.(kv, :second))...)
16+
l,u = -minimum(ks),maximum(ks)
17+
c = zeros(T, l+u+1, length(ks))
18+
for (k,j) in zip(u .- ks .+ 1,1:length(ks))
19+
c[k,j] = one(T)
20+
end
21+
_BandedMatrix(ApplyArray(*,c,rws), ∞, l, u)
22+
end
23+
1124
# Construct InfToeplitz
1225
function BandedMatrix{T}(kv::Tuple{Vararg{Pair{<:Integer,<:Fill{<:Any,1,Tuple{OneToInf{Int}}}}}},
13-
mn::NTuple{2,Integer},
26+
mn::NTuple{2,Infinity},
1427
lu::NTuple{2,Integer}) where T
1528
m,n = mn
1629
@assert isinf(n)
@@ -25,7 +38,7 @@ function BandedMatrix{T}(kv::Tuple{Vararg{Pair{<:Integer,<:Fill{<:Any,1,Tuple{On
2538
end
2639

2740
function BandedMatrix{T}(kv::Tuple{Vararg{Pair{<:Integer,<:Vcat{<:Any,1,<:Tuple{<:AbstractVector,Fill{<:Any,1,Tuple{OneToInf{Int}}}}}}}},
28-
mn::NTuple{2,Integer},
41+
mn::NTuple{2,Infinity},
2942
lu::NTuple{2,Integer}) where T
3043
m,n = mn
3144
@assert isinf(n)

src/infqr.jl

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ function lmul!(A::QRPackedQ{<:Any,<:AdaptiveQRFactors}, B::CachedVector{T,Vector
102102
b = B.data
103103

104104
sB_2 = length(b)
105+
partialqr!(A.factors.data, sB)
105106

106107
@inbounds begin
107108
for k = sB:-1:1
@@ -131,22 +132,30 @@ function lmul!(adjA::Adjoint{<:Any,<:QRPackedQ{<:Any,<:AdaptiveQRFactors}}, B::C
131132
end
132133
Afactors = A.factors
133134
sB = length(B.data)
135+
partialqr!(A.factors.data, min(sB+100,nA))
136+
resizedata!(B, min(sB+100,mB))
137+
Bd = B.data
134138
@inbounds begin
135139
for k = 1:min(mA,nA)
136140
vBj = B[k]
137141
allzero = k > sB ? iszero(vBj) : false
138142
cs = colsupport(Afactors,k)
143+
cs_max = maximum(cs)
144+
if cs_max > length(Bd) # need to grow the data
145+
resizedata!(B, min(cs_max+100,mB)); Bd = B.data
146+
partialqr!(A.factors.data, min(cs_max+100,nA))
147+
end
139148
for i = (k+1:mB) cs
140-
Bi = B[i]
149+
Bi = Bd[i]
141150
if !iszero(Bi)
142151
allzero = false
143152
vBj += conj(Afactors[i,k])*Bi
144153
end
145154
end
146155
vBj = conj(A.τ[k])*vBj
147-
B[k] -= vBj
156+
Bd[k] -= vBj
148157
for i = (k+1:mB) cs
149-
B[i] -= Afactors[i,k]*vBj
158+
Bd[i] -= Afactors[i,k]*vBj
150159
end
151160
allzero && break
152161
end

test/runtests.jl

Lines changed: 26 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,32 +2,23 @@ using InfiniteLinearAlgebra, BlockBandedMatrices, BlockArrays, BandedMatrices, I
22
import InfiniteLinearAlgebra: qltail, toeptail, tailiterate , tailiterate!, tail_de, ql_X!,
33
InfToeplitz, PertToeplitz, TriToeplitz, InfBandedMatrix,
44
rightasymptotics, QLHessenberg
5+
56
import BlockArrays: _BlockArray
67
import BlockBandedMatrices: isblockbanded, _BlockBandedMatrix
78
import MatrixFactorizations: QLPackedQ
89
import BandedMatrices: bandeddata, _BandedMatrix
910
import LazyArrays: colsupport, ApplyStyle, MemoryLayout
1011

11-
@testset "Algebra" begin
12-
@testset "BlockTridiagonal" begin
13-
A = BlockTridiagonal(Vcat([fill(1.0,2,1),Matrix(1.0I,2,2),Matrix(1.0I,2,2),Matrix(1.0I,2,2)],Fill(Matrix(1.0I,2,2), ∞)),
14-
Vcat([zeros(1,1)], Fill(zeros(2,2), ∞)),
15-
Vcat([fill(1.0,1,2),Matrix(1.0I,2,2)], Fill(Matrix(1.0I,2,2), ∞)))
16-
17-
@test A isa InfiniteLinearAlgebra.BlockTriPertToeplitz
18-
@test isblockbanded(A)
1912

20-
@test A[Block.(1:2),Block(1)] == A[1:3,1:1] == reshape([0.,1.,1.],3,1)
2113

22-
@test BlockBandedMatrix(A)[1:100,1:100] == BlockBandedMatrix(A,(2,1))[1:100,1:100] == BlockBandedMatrix(A,(1,1))[1:100,1:100] == A[1:100,1:100]
2314

24-
@test (A - I)[1:100,1:100] == A[1:100,1:100]-I
25-
@test (A + I)[1:100,1:100] == A[1:100,1:100]+I
26-
@test (I + A)[1:100,1:100] == I+A[1:100,1:100]
27-
@test (I - A)[1:100,1:100] == I-A[1:100,1:100]
28-
end
29-
15+
16+
@testset "Algebra" begin
3017
@testset "BandedMatrix" begin
18+
A = BandedMatrix(-3 => Fill(7/10,∞), -2 => 1:∞, 1 => Fill(2im,∞))
19+
@test A isa BandedMatrix{ComplexF64}
20+
@test A[1:10,1:10] == diagm(-3 => Fill(7/10,7), -2 => 1:8, 1 => Fill(2im,9))
21+
3122
A = BandedMatrix(-3 => Fill(7/10,∞), -2 => Fill(1,∞), 1 => Fill(2im,∞))
3223
Ac = BandedMatrix(A')
3324
At = BandedMatrix(transpose(A))
@@ -52,6 +43,25 @@ import LazyArrays: colsupport, ApplyStyle, MemoryLayout
5243
@test (A^3)[1:10,1:10] == (A*A*A)[1:10,1:10] == (A[1:100,1:100]^3)[1:10,1:10]
5344
end
5445

46+
@testset "BlockTridiagonal" begin
47+
A = BlockTridiagonal(Vcat([fill(1.0,2,1),Matrix(1.0I,2,2),Matrix(1.0I,2,2),Matrix(1.0I,2,2)],Fill(Matrix(1.0I,2,2), ∞)),
48+
Vcat([zeros(1,1)], Fill(zeros(2,2), ∞)),
49+
Vcat([fill(1.0,1,2),Matrix(1.0I,2,2)], Fill(Matrix(1.0I,2,2), ∞)))
50+
51+
@test A isa InfiniteLinearAlgebra.BlockTriPertToeplitz
52+
@test isblockbanded(A)
53+
54+
@test A[Block.(1:2),Block(1)] == A[1:3,1:1] == reshape([0.,1.,1.],3,1)
55+
56+
@test BlockBandedMatrix(A)[1:100,1:100] == BlockBandedMatrix(A,(2,1))[1:100,1:100] == BlockBandedMatrix(A,(1,1))[1:100,1:100] == A[1:100,1:100]
57+
58+
@test (A - I)[1:100,1:100] == A[1:100,1:100]-I
59+
@test (A + I)[1:100,1:100] == A[1:100,1:100]+I
60+
@test (I + A)[1:100,1:100] == I+A[1:100,1:100]
61+
@test (I - A)[1:100,1:100] == I-A[1:100,1:100]
62+
end
63+
64+
5565
@testset "Fill" begin
5666
A = _BandedMatrix(Ones(1,∞),∞,-1,1)
5767
@test 1.0 .* A isa BandedMatrix{Float64,<:Fill}

test/test_infqr.jl

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using InfiniteLinearAlgebra, LinearAlgebra, BandedMatrices, InfiniteArrays, MatrixFactorizations, LazyArrays, FillArrays
1+
using InfiniteLinearAlgebra, LinearAlgebra, BandedMatrices, InfiniteArrays, MatrixFactorizations, LazyArrays, FillArrays, SpecialFunctions
22
import LazyArrays: colsupport, rowsupport, MemoryLayout, DenseColumnMajor, TriangularLayout
33
import BandedMatrices: _BandedMatrix, _banded_qr!, BandedColumns
44
import InfiniteLinearAlgebra: partialqr!, AdaptiveQRData, AdaptiveLayout
@@ -76,9 +76,22 @@ import InfiniteLinearAlgebra: partialqr!, AdaptiveQRData, AdaptiveLayout
7676

7777
@test Q'*b == r
7878

79+
@test factorize(A) isa typeof(qr(A))
7980
@test qr(A)\b == A\b
8081
@test (A*(A\b))[1:100] [1:3; Zeros(97)]
8182
end
83+
84+
@testset "Bessel J" begin
85+
z = 1000; # the bigger z the longer before we see convergence
86+
A = BandedMatrix(0 => -2*(0:∞)/z, 1 => Ones(∞), -1 => Ones(∞))
87+
J = A \ Vcat([besselj(1,z)], Zeros(∞))
88+
@test J[1:2000] [besselj(k,z) for k=0:1999]
89+
90+
z = 10_000; # the bigger z the longer before we see convergence
91+
A = BandedMatrix(0 => -2*(0:∞)/z, 1 => Ones(∞), -1 => Ones(∞))
92+
J = A \ Vcat([besselj(1,z)], Zeros(∞))
93+
@test J[1:20_000] [besselj(k,z) for k=0:20_000-1]
94+
end
8295
end
8396

8497

0 commit comments

Comments
 (0)