Skip to content

Commit b45feb0

Browse files
authored
QuasiArrays v0.5 (#85)
* tests pass * update tests * v0.6.5 * Hcat improvements, transform matrix * Update Project.toml * add tests * Test factorization
1 parent 732bd28 commit b45feb0

File tree

8 files changed

+79
-40
lines changed

8 files changed

+79
-40
lines changed

Project.toml

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
name = "ContinuumArrays"
22
uuid = "7ae1f121-cc2c-504b-ac30-9b923412ae5c"
3-
version = "0.6.4"
3+
version = "0.7.0"
44

55
[deps]
66
ArrayLayouts = "4c555306-a7a7-4459-81d9-ec55ddd5c99a"
77
BandedMatrices = "aae01518-5342-5314-be14-df237901396f"
88
BlockArrays = "8e7c35d0-a365-5155-bbbb-fb81a777f24e"
9+
FastTransforms = "057dd010-8810-581a-b7be-e3fc3b93f78c"
910
FillArrays = "1a297f60-69ca-5386-bcde-b61e274b549b"
1011
InfiniteArrays = "4858937d-0d70-526a-a4dd-2d5cb5dd786c"
1112
Infinities = "e1ba4f0e-776d-440f-acd9-e1d2e9742647"
@@ -16,15 +17,15 @@ QuasiArrays = "c4ea9172-b204-11e9-377d-29865faadc5c"
1617
StaticArrays = "90137ffa-7385-5640-81b9-e52037218182"
1718

1819
[compat]
19-
ArrayLayouts = "0.5, 0.6"
20+
ArrayLayouts = "0.6"
2021
BandedMatrices = "0.16"
2122
BlockArrays = "0.15.1"
2223
FillArrays = "0.11"
23-
InfiniteArrays = "0.9, 0.10"
24-
Infinities = "0.0.1, 0.0.2, 0.1"
24+
InfiniteArrays = "0.10"
25+
Infinities = "0.1"
2526
IntervalSets = "0.5"
26-
LazyArrays = "0.20, 0.21"
27-
QuasiArrays = "0.4.1"
27+
LazyArrays = "0.21"
28+
QuasiArrays = "0.5.1"
2829
StaticArrays = "0.12, 1"
2930
julia = "1.5"
3031

src/ContinuumArrays.jl

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import Base.Broadcast: materialize, BroadcastStyle, broadcasted
88
import LazyArrays: MemoryLayout, Applied, ApplyStyle, flatten, _flatten, colsupport, most, combine_mul_styles, AbstractArrayApplyStyle,
99
adjointlayout, arguments, _mul_arguments, call, broadcastlayout, layout_getindex, UnknownLayout,
1010
sublayout, sub_materialize, ApplyLayout, BroadcastLayout, combine_mul_styles, applylayout,
11-
simplifiable, _simplify
11+
simplifiable, _simplify, AbstractLazyLayout
1212
import LinearAlgebra: pinv, dot, norm2
1313
import BandedMatrices: AbstractBandedLayout, _BandedMatrix
1414
import BlockArrays: block, blockindex, unblock, blockedrange, _BlockedUnitRange, _BlockArray
@@ -17,7 +17,8 @@ import ArrayLayouts: mul
1717
import QuasiArrays: cardinality, checkindex, QuasiAdjoint, QuasiTranspose, Inclusion, SubQuasiArray,
1818
QuasiDiagonal, MulQuasiArray, MulQuasiMatrix, MulQuasiVector, QuasiMatMulMat,
1919
ApplyQuasiArray, ApplyQuasiMatrix, LazyQuasiArrayApplyStyle, AbstractQuasiArrayApplyStyle, AbstractQuasiLazyLayout,
20-
LazyQuasiArray, LazyQuasiVector, LazyQuasiMatrix, LazyLayout, LazyQuasiArrayStyle, _factorize
20+
LazyQuasiArray, LazyQuasiVector, LazyQuasiMatrix, LazyLayout, LazyQuasiArrayStyle, _factorize,
21+
AbstractQuasiFill, UnionDomain
2122
import InfiniteArrays: Infinity, InfAxes
2223

2324
export Spline, LinearSpline, HeavisideSpline, DiracDelta, Derivative, ℵ₁, Inclusion, Basis, WeightedBasis, grid, transform, affine, ..
@@ -78,6 +79,7 @@ end
7879
(inds[1][I[1]], to_indices(A, _maybetail(inds), tail(I))...)
7980

8081
checkpoints(d::AbstractInterval{T}) where T = width(d) .* SVector{3,float(T)}(0.823972,0.01,0.3273484) .+ leftendpoint(d)
82+
checkpoints(d::UnionDomain) = mapreduce(checkpoints,union,d.domains)
8183
checkpoints(x::Inclusion) = checkpoints(x.domain)
8284
checkpoints(A::AbstractQuasiMatrix) = checkpoints(axes(A,1))
8385

src/bases/bases.jl

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -139,10 +139,21 @@ grid(T::TransformFactorization) = T.grid
139139

140140
\(a::TransformFactorization{<:Any,<:Any,Nothing}, b::AbstractQuasiVector{T}) where T = a.iplan \ convert(Array{T}, b[a.grid])
141141
\(a::TransformFactorization, b::AbstractQuasiVector) = a.plan * convert(Array, b[a.grid])
142-
143142
\(a::TransformFactorization{<:Any,<:Any,Nothing}, b::AbstractVector) = a.iplan \ b
144143
\(a::TransformFactorization, b::AbstractVector) = a.plan * b
145144

145+
\(a::TransformFactorization{<:Any,<:Any,Nothing}, b::AbstractQuasiMatrix{T}) where T = a \ convert(Array{T}, b[a.grid,:])
146+
\(a::TransformFactorization, b::AbstractQuasiMatrix) = a \ convert(Array, b[a.grid,:])
147+
function \(a::TransformFactorization, b::AbstractMatrix)
148+
c = a \ b[:,1]
149+
ret = Array{eltype(c)}(undef, length(c), size(b,2))
150+
ret[:,1] = c
151+
for k = 2:size(ret,2)
152+
ret[:,k] = a \ b[:,k]
153+
end
154+
ret
155+
end
156+
146157
function _factorize(::AbstractBasisLayout, L)
147158
p = grid(L)
148159
TransformFactorization(p, nothing, factorize(L[p,:]))
@@ -177,11 +188,11 @@ end
177188
transform_ldiv(A, B, _) = factorize(A) \ B
178189
transform_ldiv(A, B) = transform_ldiv(A, B, size(A))
179190

180-
copy(L::Ldiv{<:AbstractBasisLayout,<:Any,<:Any,<:AbstractQuasiVector}) =
181-
transform_ldiv(L.A, L.B)
182-
183-
copy(L::Ldiv{<:AbstractBasisLayout,ApplyLayout{typeof(*)},<:Any,<:AbstractQuasiVector}) =
184-
transform_ldiv(L.A, L.B)
191+
copy(L::Ldiv{<:AbstractBasisLayout}) = transform_ldiv(L.A, L.B)
192+
# TODO: redesign to use simplifiable(\, A, B)
193+
copy(L::Ldiv{<:AbstractBasisLayout,ApplyLayout{typeof(*)},<:Any,<:AbstractQuasiVector}) = transform_ldiv(L.A, L.B)
194+
copy(L::Ldiv{<:AbstractBasisLayout,ApplyLayout{typeof(*)}}) = copy(Ldiv{UnknownLayout,ApplyLayout{typeof(*)}}(L.A, L.B))
195+
copy(L::Ldiv{<:AbstractBasisLayout,<:AbstractLazyLayout}) = transform_ldiv(L.A, L.B)
185196

186197
struct WeightedFactorization{T, WW, FAC<:Factorization{T}} <: Factorization{T}
187198
w::WW

src/basisconcat.jl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,3 +108,6 @@ function QuasiArrays._getindex(::Type{IND}, A::HvcatBasis{T}, (x,j)::IND) where
108108
J = Int(block(Jj))
109109
hvcat(A.n, zeros(J-1)..., A.args[J][x, blockindex(Jj)], zeros(length(A.args)-J)...)::T
110110
end
111+
112+
113+
@simplify *(D::Derivative, H::ApplyQuasiMatrix{<:Any,typeof(hcat)}) = hcat((Ref(D) .* H.args)...)

src/maps.jl

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -91,8 +91,9 @@ broadcasted(::LazyQuasiArrayStyle{1}, ::typeof(+), x::AbstractAffineQuasiVector,
9191
broadcasted(::LazyQuasiArrayStyle{1}, ::typeof(-), a::Number, x::AbstractAffineQuasiVector) = AffineQuasiVector(-one(eltype(x)), x, a)
9292
broadcasted(::LazyQuasiArrayStyle{1}, ::typeof(-), x::AbstractAffineQuasiVector, b::Number) = AffineQuasiVector(one(eltype(x)), x, -b)
9393

94-
Base.@propagate_inbounds checkindex(::Type{Bool}, inds::Inclusion{<:Any,<:AbstractInterval}, r::Inclusion{<:Any,<:AbstractInterval}) = QuasiArrays._affine_checkindex(inds, r)
95-
Base.@propagate_inbounds checkindex(::Type{Bool}, inds::Inclusion{<:Any,<:AbstractInterval}, r::AbstractAffineQuasiVector) = QuasiArrays._affine_checkindex(inds, r)
94+
Base.@propagate_inbounds _affine_checkindex(inds, r) = isempty(r) | (checkindex(Bool, inds, Base.to_indices(inds, (first(r),))...) & checkindex(Bool, inds, Base.to_indices(inds, (last(r),))...))
95+
Base.@propagate_inbounds checkindex(::Type{Bool}, inds::Inclusion{<:Any,<:AbstractInterval}, r::Inclusion{<:Any,<:AbstractInterval}) = _affine_checkindex(inds, r)
96+
Base.@propagate_inbounds checkindex(::Type{Bool}, inds::Inclusion{<:Any,<:AbstractInterval}, r::AbstractAffineQuasiVector) = _affine_checkindex(inds, r)
9697

9798
minimum(d::AbstractAffineQuasiVector) = signbit(d.A) ? last(d) : first(d)
9899
maximum(d::AbstractAffineQuasiVector) = signbit(d.A) ? first(d) : last(d)
@@ -112,7 +113,7 @@ end
112113
AffineMap(domain::AbstractQuasiVector{T}, range::AbstractQuasiVector{V}) where {T,V} =
113114
AffineMap{promote_type(T,V), typeof(domain),typeof(range)}(domain,range)
114115

115-
measure(x::Inclusion) = last(x)-first(x)
116+
measure(x::Inclusion{<:Any,<:AbstractInterval}) = last(x)-first(x)
116117

117118
function getproperty(A::AffineMap, d::Symbol)
118119
domain, range = getfield(A, :domain), getfield(A, :range)

src/operators.jl

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,6 @@ end
6868
DiracDelta{T}(x, axis::A) where {T,A<:AbstractQuasiVector} = DiracDelta{T,A}(x, axis)
6969
DiracDelta{T}(x, domain) where T = DiracDelta{T}(x, Inclusion(domain))
7070
DiracDelta(x, domain) = DiracDelta{float(eltype(x))}(x, Inclusion(domain))
71-
DiracDelta(axis::AbstractQuasiVector) = DiracDelta(zero(float(eltype(axis))), axis)
7271
DiracDelta(x) = DiracDelta(x, Inclusion(x))
7372
DiracDelta{T}() where T = DiracDelta(zero(T))
7473
DiracDelta() = DiracDelta{Float64}()
@@ -129,3 +128,6 @@ end
129128
const Identity{T,D} = QuasiDiagonal{T,Inclusion{T,D}}
130129

131130
Identity(d::Inclusion) = QuasiDiagonal(d)
131+
132+
@simplify *(D::Derivative, x::Inclusion) = ones(promote_type(eltype(D),eltype(x)), x)
133+
@simplify *(D::Derivative, c::AbstractQuasiFill) = zeros(promote_type(eltype(D),eltype(c)), axes(c,1))

test/runtests.jl

Lines changed: 39 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -7,25 +7,37 @@ import LazyArrays: MemoryLayout, ApplyStyle, Applied, colsupport, arguments, App
77

88

99
@testset "Inclusion" begin
10-
x = Inclusion(-1..1)
11-
@test eltype(x) == Float64
12-
@test x[0.1] 0.1
13-
@test x[0] x[0.0] 0.0
14-
15-
x = Inclusion(-1.0..1)
16-
X = QuasiDiagonal(x)
17-
@test X[-1:0.1:1,-1:0.1:1] == Diagonal(-1:0.1:1)
18-
@test Base.BroadcastStyle(typeof(x)) == LazyQuasiArrayStyle{1}()
19-
@test x .* x isa BroadcastQuasiArray
20-
@test (x.*x)[0.1] == 0.1^2
21-
22-
@test exp.(x)[1.0] == exp(1.0)
23-
@test exp.(-x)[1.0] == exp(-1.0)
24-
@test exp.(x.^2)[1.0] == exp(1.0)
25-
@test exp.(-x.^2/(20/2))[1.0] == exp(-1.0^2/(20/2))
26-
27-
@test dot(x,x) 2/3
28-
@test norm(x) sqrt(2/3)
10+
@testset "basics" begin
11+
x = Inclusion(-1..1)
12+
@test eltype(x) == Float64
13+
@test x[0.1] 0.1
14+
@test x[0] x[0.0] 0.0
15+
end
16+
17+
@testset "broadcast" begin
18+
x = Inclusion(-1.0..1)
19+
X = QuasiDiagonal(x)
20+
@test X[-1:0.1:1,-1:0.1:1] == Diagonal(-1:0.1:1)
21+
@test Base.BroadcastStyle(typeof(x)) == LazyQuasiArrayStyle{1}()
22+
@test x .* x isa BroadcastQuasiArray
23+
@test (x.*x)[0.1] == 0.1^2
24+
25+
@test exp.(x)[1.0] == exp(1.0)
26+
@test exp.(-x)[1.0] == exp(-1.0)
27+
@test exp.(x.^2)[1.0] == exp(1.0)
28+
@test exp.(-x.^2/(20/2))[1.0] == exp(-1.0^2/(20/2))
29+
30+
@test dot(x,x) 2/3
31+
@test norm(x) sqrt(2/3)
32+
end
33+
34+
@testset "Derivative" begin
35+
x = Inclusion(-1..1)
36+
D = Derivative(x)
37+
@test D*x QuasiOnes(x)
38+
@test D^2 * x QuasiZeros(x)
39+
@test D*[x D*x] == [D*x D^2*x]
40+
end
2941
end
3042

3143
include("test_maps.jl")
@@ -76,7 +88,7 @@ end
7688
@test_throws BoundsError H[[0.1,2.1], 1]
7789
@test MemoryLayout(typeof(H)) == BasisLayout()
7890
@test ApplyStyle(*, typeof(H), typeof([1,2])) isa MulStyle
79-
91+
8092
f = H*[1,2]
8193
@test f isa ApplyQuasiArray
8294
@test axes(f) == (Inclusion(1.0..3.0),)
@@ -189,6 +201,8 @@ end
189201
f = L*[1,2,4]
190202

191203
D = Derivative(axes(L,1))
204+
@test copy(D) == D
205+
192206
@test D*L isa MulQuasiMatrix
193207
@test length((D*L).args) == 2
194208
@test eltype(D*L) == Float64
@@ -316,6 +330,8 @@ end
316330
@test (L \ x) == [1,2,3]
317331
@test factorize(L[:,2:end-1]) isa ContinuumArrays.ProjectionFactorization
318332
@test L[:,1:2] \ x == [1,2]
333+
@test L \ [x one(x)] [L\x L\one(x)]
334+
@test factorize(L) \ QuasiOnes(x, Base.OneTo(3)) L \ QuasiOnes(x, Base.OneTo(3)) ones(3,3)
319335

320336
L = LinearSpline(range(0,1; length=10_000))
321337
x = axes(L,1)
@@ -494,6 +510,8 @@ ContinuumArrays.invmap(::InvQuadraticMap{T}) where T = QuadraticMap{T}()
494510
g = grid(F)
495511
@test T \ exp.(x) == F \ exp.(x) == F \ exp.(g) == chebyshevtransform(exp.(g), Val(1))
496512
@test all(checkpoints(T) .∈ Ref(axes(T,1)))
513+
514+
@test F \ [exp.(x) cos.(x)] [F \ exp.(x) F \ cos.(x)]
497515
end
498516

499517
@testset "Weighted" begin
@@ -533,7 +551,7 @@ ContinuumArrays.invmap(::InvQuadraticMap{T}) where T = QuadraticMap{T}()
533551
@test 2 m
534552
@test 0.1 mi
535553
@test -0.1 mi
536-
554+
537555
@test m[findfirst(isequal(0.1), m)] 0.1
538556
@test m[findlast(isequal(0.1), m)] 0.1
539557
@test m[findall(isequal(0.1), m)] [0.1]

test/test_basisconcat.jl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
using ContinuumArrays, BlockArrays, Test
2-
import ContinuumArrays: PiecewiseBasis, VcatBasis, HvcatBasis, arguments, ApplyLayout
2+
import ContinuumArrays: PiecewiseBasis, VcatBasis, HvcatBasis, arguments, ApplyLayout, checkpoints
33

44
@testset "ConcatBasis" begin
55
@testset "PiecewiseBasis" begin
@@ -8,6 +8,7 @@ import ContinuumArrays: PiecewiseBasis, VcatBasis, HvcatBasis, arguments, ApplyL
88
S = PiecewiseBasis(S1, S2)
99

1010
@test S == S
11+
@test checkpoints(S) == union(checkpoints(S1), checkpoints(S2))
1112

1213
@test S[0.5,1:4] == [S1[0.5,1:2]; zeros(2)]
1314
@test S[2.5,1:4] == [zeros(2); S2[2.5,1:2]]

0 commit comments

Comments
 (0)