Skip to content

Commit 518fbb8

Browse files
committed
Views and PDEs
1 parent b2f5afd commit 518fbb8

File tree

3 files changed

+52
-66
lines changed

3 files changed

+52
-66
lines changed

src/QuasiArrays/matmul.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ function getindex(M::QuasiMatMulVec, k::AbstractArray)
2323
A,B = M.factors
2424
ret = zeros(eltype(M),length(k))
2525
@inbounds for j = 1:size(A,2)
26-
ret .+= Mul(view(A,k,j) , B[j])
26+
ret .+= view(A,k,j) .* B[j]
2727
end
2828
ret
2929
end

src/bases/splines.jl

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,17 @@ function copyto!(dest::SymTridiagonal, AB::Mul2{<:Any,<:Any,<:Adjoint{<:Any,<:Li
5757
dest
5858
end
5959

60+
## Sub-bases
61+
# we represent as a Mul with a banded matrix
62+
function materialize(V::SubQuasiArray{<:Any,2,<:Spline,<:Tuple{<:QSlice,<:AbstractUnitRange}})
63+
A = parent(V)
64+
_,jr = parentindices(V)
65+
first(jr) 1 || throw(BoundsError())
66+
P = BandedMatrix((1-first(jr) => Ones{Int}(length(jr)),), (size(A,2), length(jr)))
67+
A*P
68+
end
69+
70+
6071
## Mass matrix
6172
function similar(AB::Mul2{<:Any,<:Any,<:Adjoint{<:Any,<:LinearSpline},<:LinearSpline}, ::Type{T}) where T
6273
n = size(AB,1)

test/runtests.jl

Lines changed: 40 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -103,93 +103,68 @@ end
103103
@test view(L,0.1,1)[1] == L[0.1,1]
104104

105105
L = LinearSpline(0:2)
106-
B1 = L[:,1]
106+
B1 = view(L,:,1)
107107
@test B1 isa SubQuasiArray{Float64,1}
108108
@test size(B1) == (ℵ₁,)
109109
@test B1[0.1] == L[0.1,1]
110110
@test_throws BoundsError B1[2.2]
111111

112-
B = L[:,1:2]
112+
B = view(L,:,1:2)
113113
@test B isa SubQuasiArray{Float64,2}
114114
@test B[0.1,:] == L[0.1,1:2]
115115

116-
B = L[:,2:end-1]
116+
B = @view L[:,2:end-1]
117117
@test B[0.1,:] == [0.1]
118118
end
119119

120-
A = randn(4,4)
121-
@which lastindex(A,2)
122120

123-
@time begin
124-
L = LinearSpline(range(0,stop=1,length=10))[:,2:end-1]
125-
D = Derivative(axes(L,1))
126-
127-
D*L
128-
129-
Derivative(0..1)*parent(L)
130-
131-
132-
133-
134-
M = Mul(D,L)
135-
A, B = M.factors
136-
axes(A,2) == axes(B,1) || throw(DimensionMismatch())
137-
P = parent(B)
138-
(Derivative(axes(P,1))*P)[parentindices(P)...]
139-
140-
@which axes(D,2)
141-
142-
axes(D,2)
143-
D*L
144-
A = -(L'D'D*L)
145-
f = L*exp.(L.points)
146-
147-
A \ (L'f)
148-
149-
u = A[2:end-1,2:end-1] \ (L'f)[2:end-1]
150-
151-
cond(A[2:end-1,2:end-1])
152-
153-
A[2:end-1,2:end-1] *u - (L'f)[2:end-1]
154-
155-
v = L*[0; u; 0]
156-
157-
158-
v[0.2]
159-
using Plots
160-
plot(0:0.01:1,getindex.(Ref(v),0:0.01:1))
161-
plot!(u1)
162-
ui
163-
164-
using ApproxFun
165-
166-
x = Fun(0..1)
167-
u1 = [Dirichlet(Chebyshev(0..1)); ApproxFun.Derivative()^2] \ [[0,0], exp(x)]
168-
169-
plot(u1)
170-
171-
u_ex = L*u1.(L.points)
172-
173-
xx = 0:0.01:1;
174-
plot(xx,getindex.(Ref(D*u_ex),xx))
121+
@testset "Subindex of splines" begin
122+
L = LinearSpline(range(0,stop=1,length=10))
123+
@test L[:,2:end-1] isa Mul
124+
@test_broken L[:,2:end-1][0.1,1] == L[0.1,2]
125+
v = randn(8)
126+
f = L[:,2:end-1] * v
127+
@test f[0.1] (L*[0; v; 0])[0.1]
128+
end
175129

176-
getindex.(Ref(D*u_ex),xx)
177-
plot!(u1')
130+
@testset "Poisson" begin
131+
L = LinearSpline(range(0,stop=1,length=10))
132+
B = L[:,2:end-1] # Zero dirichlet by dropping first and last spline
133+
D = Derivative(axes(L,1))
134+
Δ = -(B'D'D*B) # Weak Laplacian
178135

179-
f[0.1]-exp(0.1)
136+
f = L*exp.(L.points) # project exp(x)
137+
u = B *\ (B'f))
180138

181-
(D*v)'*(D*v)
139+
@test u[0.1] -0.06612902692412974
140+
end
182141

183142

143+
@testset "Helmholtz" begin
144+
L = LinearSpline(range(0,stop=1,length=10))
145+
B = L[:,2:end-1] # Zero dirichlet by dropping first and last spline
146+
D = Derivative(axes(L,1))
147+
A = -(B'D'D*B) + 100^2*B'B # Weak Laplacian
184148

185-
L'f
149+
f = L*exp.(L.points) # project exp(x)
150+
u = B * (A \ (B'f))
186151

152+
@test u[0.1] 0.00012678835289369413
153+
end
187154

188155

156+
L = LinearSpline(range(0,stop=1,length=20_000_000))
157+
B = L[:,2:end-1] # Zero dirichlet by dropping first and last spline
189158

159+
k = 10_000
160+
@time A = -(B'D'D*B) + k^2*B'B # Weak Helmholtz, 9s
161+
@time f = L*exp.(L.points) # project exp(x), 0.3s
162+
@time u = B * (A \ (B'f)) # solution, 4s
190163

191-
(L'f)
192164

193-
(L'f)
165+
# Compare with "exact" solution
166+
using Plots, ApproxFun
194167

195-
end
168+
x = Fun(axes(L,1))
169+
u_ex = [Dirichlet(Chebyshev(0..1)); ApproxFun.Derivative()^2 + k^2*I] \ [[0,0], exp(x)]
170+
@test u[0.1] u_ex(0.1) rtol = 1E-3

0 commit comments

Comments
 (0)