Skip to content

Commit 9cbbd61

Browse files
committed
Add lowering operators
1 parent fe83413 commit 9cbbd61

File tree

3 files changed

+151
-8
lines changed

3 files changed

+151
-8
lines changed

src/QuasiArrays/matmul.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ end
3232
QuasiMatMulMat{styleA, styleB, T, V} = QuasiArrayMulArray{styleA, styleB, 2, 2, T, V}
3333
QuasiMatMulQuasiMat{styleA, styleB, T, V} = QuasiArrayMulQuasiArray{styleA, styleB, 2, 2, T, V}
3434

35-
*(A::AbstractQuasiArray, B::AbstractQuasiArray, C::AbstractQuasiArray) = materialize(Mul(A,B,C))
35+
*(A::AbstractQuasiArray, B::AbstractQuasiArray, C::AbstractQuasiArray, D::AbstractQuasiArray...) = materialize(Mul(A,B,C,D...))
3636
*(A::AbstractQuasiArray, B::AbstractQuasiArray) = materialize(Mul(A,B))
3737
*(A::AbstractQuasiArray, B::AbstractArray) = materialize(Mul(A,B))
3838
*(A::AbstractArray, B::AbstractQuasiArray) = materialize(Mul(A,B))

src/bases/jacobi.jl

Lines changed: 73 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,18 +26,85 @@ axes(::AbstractJacobi) = (ChebyshevInterval(), OneTo(∞))
2626
materialize(M::Mul2{<:Any,<:Any,<:QuasiAdjoint{<:Any,<:Legendre},<:Legendre}) =
2727
Diagonal(2 ./ (2(0:∞) .+ 1))
2828

29+
# pinv(Jacobi(b+1,a+1))D*W*Jacobi(a,b)
30+
function materialize(M::Mul{<:Tuple,<:Tuple{<:PInv{<:Any,<:Jacobi},
31+
<:Derivative{<:Any,<:ChebyshevInterval},
32+
<:Jacobi}})
33+
Ji, D, S = M.factors
34+
J = parent(Ji)
35+
(J.b == S.b+1 && J.a == S.a+1) || throw(ArgumentError())
36+
_BandedMatrix(((1:.+ 1 .+ S.a .+ S.b)/2)', ∞, -1,1)
37+
end
38+
2939

3040
function materialize(M::Mul2{<:Any,<:Any,<:Derivative{<:Any,<:ChebyshevInterval},<:Jacobi})
31-
_, S = M.factors
32-
D = _BandedMatrix(((1:.+ 1 .+ S.a .+ S.b)/2)', ∞, -1,1)
33-
Mul(Jacobi(S.a+1,S.b+1), D)
41+
D, S = M.factors
42+
A = PInv(Jacobi(S.b+1,S.a+1))*D*S
43+
Mul(Jacobi(S.b+1,S.a+1), A)
44+
end
45+
46+
# pinv(Legendre())D*W*Jacobi(true,true)
47+
function materialize(M::Mul{<:Tuple,<:Tuple{<:PInv{<:Any,<:Legendre},
48+
<:Derivative{<:Any,<:ChebyshevInterval},
49+
QuasiDiagonal{Bool,JacobiWeight{Bool}},Jacobi{Bool}}})
50+
Li, _, W, S = M.factors
51+
w = parent(W)
52+
(w.a && S.a && w.b && S.b) || throw(ArgumentError())
53+
_BandedMatrix((-2*(1:∞))', ∞, 1,-1)
3454
end
3555

56+
# reduce to Legendre
3657
function materialize(M::Mul{<:Tuple,<:Tuple{<:Derivative{<:Any,<:ChebyshevInterval},
3758
QuasiDiagonal{Bool,JacobiWeight{Bool}},Jacobi{Bool}}})
38-
_, W, S = M.factors
59+
D, W, S = M.factors
3960
w = parent(W)
4061
(w.a && S.a && w.b && S.b) || throw(ArgumentError())
41-
D = _BandedMatrix((-2*(1:∞))', ∞, 1,-1)
42-
Mul(Legendre(), D)
62+
A = pinv(Legendre{eltype(M)}())*D*W*S
63+
Mul(Legendre(), A)
64+
end
65+
66+
function materialize(M::Mul{<:Tuple,<:Tuple{<:PInv{<:Any,<:Jacobi{Bool}},
67+
QuasiDiagonal{Bool,JacobiWeight{Bool}},Jacobi{Bool}}})
68+
Ji, W, S = M.factors
69+
J,w = parent(Ji),parent(W)
70+
@assert S.b && S.a
71+
if w.b && !w.a
72+
@assert !J.b && J.a
73+
_BandedMatrix(Vcat(((2:2:∞)./(3:2:∞))',((2:2:∞)./(3:2:∞))'), ∞, 1,0)
74+
elseif !w.b && w.a
75+
@assert J.b && !J.a
76+
_BandedMatrix(Vcat(((2:2:∞)./(3:2:∞))',(-(2:2:∞)./(3:2:∞))'), ∞, 1,0)
77+
else
78+
error("Not implemented")
79+
end
80+
end
81+
82+
function materialize(M::Mul{<:Tuple,<:Tuple{<:PInv{<:Any,<:Legendre},
83+
QuasiDiagonal{Bool,JacobiWeight{Bool}},Jacobi{Bool}}})
84+
Li, W, S = M.factors
85+
L,w = parent(Li),parent(W)
86+
if w.b && w.a
87+
@assert S.b && S.a
88+
_BandedMatrix(Vcat(((2:2:∞)./(3:2:∞))', Zeros(1,∞), (-(2:2:∞)./(3:2:∞))'), ∞, 2,0)
89+
elseif w.b && !w.a
90+
@assert S.b && !S.a
91+
_BandedMatrix(Ones{eltype(M)}(2,∞), ∞, 1,0)
92+
elseif !w.b && w.a
93+
@assert !S.b && S.a
94+
_BandedMatrix(Vcat(Ones{eltype(M)}(1,∞),-Ones{eltype(M)}(1,∞)), ∞, 1,0)
95+
else
96+
error("Not implemented")
97+
end
98+
end
99+
100+
function materialize(M::Mul{<:Tuple,<:Tuple{QuasiAdjoint{Bool,Jacobi{Bool}},
101+
QuasiDiagonal{Int,JacobiWeight{Int}},Jacobi{Bool}}})
102+
St, W, S = M.factors
103+
104+
w = parent(W)
105+
(w.b == 2 && S.b && w.a == 2 && S.a && parent(St) == S) || throw(ArgumentError())
106+
W_sqrt = Diagonal(JacobiWeight(true,true))
107+
L = Legendre()
108+
A = PInv(L)*W_sqrt*S
109+
A'*(L'L)*A
43110
end

test/runtests.jl

Lines changed: 77 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,82 @@ S = Jacobi(true,true)
158158
W = Diagonal(JacobiWeight(true,true))
159159
D = Derivative(axes(W,1))
160160

161+
A = @inferred(PInv(Jacobi(2,2))*D*S)
162+
@test A isa BandedMatrix
163+
@test size(A) == (∞,∞)
164+
@test A[1:10,1:10] == diagm(1 => 1:0.5:5)
165+
166+
M = @inferred(D*S)
167+
@test M isa Mul
168+
@test M.factors[1] == Jacobi(2,2)
169+
@test M.factors[2][1:10,1:10] == A[1:10,1:10]
170+
171+
172+
L = Diagonal(JacobiWeight(true,false))
173+
A = @inferred(PInv(Jacobi(false,true))*L*S)
174+
@test A isa BandedMatrix
175+
@test size(A) == (∞,∞)
176+
177+
L = Diagonal(JacobiWeight(false,true))
178+
A = @inferred(PInv(Jacobi(true,false))*L*S)
179+
@test A isa BandedMatrix
180+
@test size(A) == (∞,∞)
181+
182+
183+
L = Diagonal(JacobiWeight(true,true))
184+
185+
186+
L = Legendre()
187+
188+
A, B = (L'L),(PInv(L)*W*S)
189+
190+
M = A*B
191+
@which M.mul[1,1]
192+
193+
@which materialize(Mul(A,B))
194+
195+
M = LazyArrays.MulArray(Mul(A,B))
196+
axes(M)
197+
198+
@time A[1:100000,1:100000]
199+
@profiler A.data[:,1:10_000]
200+
201+
V = view(A.data,:,1:100)
202+
203+
N = 10_000; M = randn(3,N)
204+
205+
A.data.arrays[2]
206+
207+
@time begin
208+
M[1,:] .= view(A.data.arrays[1]', 1:N)
209+
M[2,:] .= view(A.data.arrays[2], 1, 1:N)
210+
M[3,:] .= view(A.data.arrays[3]', 1:N)
211+
end
212+
M
213+
214+
@which copyto!(M, V)
215+
216+
@time
217+
218+
typeof(V)
219+
220+
using Profile
221+
Profile.clear()
222+
@time randn(3,10_000)
223+
224+
W*S
225+
226+
227+
228+
229+
M = Mul(S',W',W,S)
230+
materialize(M)
231+
materialize(Mul(S',W',W))
232+
233+
@which materialize(M)
234+
235+
W*W
236+
161237
S'W'W*S
162238

163239
N = 10
@@ -192,7 +268,7 @@ A.*B
192268
_Vcat(broadcast((a,b) -> broadcast(op,a,b), A_arrays, B.arrays))
193269

194270
f = Legendre() * Vcat(randn(20), Zeros(∞))
195-
@time L'f
271+
@time Vector(L'f)
196272

197273
A,v=(L'f).factors[end-1:end]
198274

0 commit comments

Comments
 (0)