Skip to content

Commit

Permalink
Support demap for Expansions (#98)
Browse files Browse the repository at this point in the history
* Support demap for Expansions

* Update runtests.jl

* Update bases.jl

* add tests

* quasimatrix ldiv

* increase coverage
  • Loading branch information
dlfivefifty committed Jun 10, 2021
1 parent a27fcb3 commit 05df318
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 15 deletions.
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name = "ContinuumArrays"
uuid = "7ae1f121-cc2c-504b-ac30-9b923412ae5c"
version = "0.8.0"
version = "0.8.1"

[deps]
ArrayLayouts = "4c555306-a7a7-4459-81d9-ec55ddd5c99a"
Expand Down
20 changes: 18 additions & 2 deletions src/bases/bases.jl
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,8 @@ function copy(P::Ldiv{<:MappedBasisLayouts,<:AbstractLazyLayout})
A,B = P.A, P.B
demap(A) \ B[invmap(basismap(A))]
end
copy(P::Ldiv{<:MappedBasisLayouts,ApplyLayout{typeof(*)}}) = copy(Ldiv{UnknownLayout,ApplyLayout{typeof(*)}}(P.A,P.B))
copy(L::Ldiv{<:MappedBasisLayouts,ApplyLayout{typeof(*)}}) = copy(Ldiv{UnknownLayout,ApplyLayout{typeof(*)}}(L.A,L.B))
copy(L::Ldiv{<:MappedBasisLayouts,ApplyLayout{typeof(*)},<:Any,<:AbstractQuasiVector}) = transform_ldiv(L.A, L.B)

@inline copy(L::Ldiv{<:AbstractBasisLayout,<:SubBasisLayouts}) = apply(\, L.A, ApplyQuasiArray(L.B))
@inline function copy(L::Ldiv{<:SubBasisLayouts,<:AbstractBasisLayout})
Expand All @@ -110,7 +111,7 @@ end
a,b = arguments(B)
@assert a isa AbstractQuasiVector # Only works for vec .* mat
ab = (A * (A \ a)) .* b # broadcasted should be overloaded
MemoryLayout(ab) isa BroadcastLayout && error("Overload broadcasted(_, ::typeof(*), ::$(typeof(ab.args[1])), ::$(typeof(b)))")
MemoryLayout(ab) isa BroadcastLayout && return transform_ldiv(A, ab)
A \ ab
end

Expand All @@ -119,6 +120,10 @@ _broadcast_mul_ldiv(_, A, B) = copy(Ldiv{typeof(MemoryLayout(A)),UnknownLayout}(
copy(L::Ldiv{<:AbstractBasisLayout,BroadcastLayout{typeof(*)}}) = _broadcast_mul_ldiv(map(MemoryLayout,arguments(L.B)), L.A, L.B)
copy(L::Ldiv{<:AbstractBasisLayout,BroadcastLayout{typeof(*)},<:Any,<:AbstractQuasiVector}) = _broadcast_mul_ldiv(map(MemoryLayout,arguments(L.B)), L.A, L.B)

# ambiguity
copy(L::Ldiv{<:MappedBasisLayouts,BroadcastLayout{typeof(*)}}) = _broadcast_mul_ldiv(map(MemoryLayout,arguments(L.B)), L.A, L.B)
copy(L::Ldiv{<:MappedBasisLayouts,BroadcastLayout{typeof(*)},<:Any,<:AbstractQuasiVector}) = _broadcast_mul_ldiv(map(MemoryLayout,arguments(L.B)), L.A, L.B)


# expansion
_grid(_, P) = error("Overload Grid")
Expand Down Expand Up @@ -172,6 +177,7 @@ struct ProjectionFactorization{T, FAC<:Factorization{T}, INDS} <: Factorization{
end

\(a::ProjectionFactorization, b::AbstractQuasiVector) = (a.F \ b)[a.inds]
\(a::ProjectionFactorization, b::AbstractQuasiMatrix) = (a.F \ b)[a.inds,:]
\(a::ProjectionFactorization, b::AbstractVector) = (a.F \ b)[a.inds]

_factorize(::SubBasisLayout, L) = ProjectionFactorization(factorize(parent(L)), parentindices(L)[2])
Expand All @@ -183,6 +189,8 @@ end

\(a::MappedFactorization, b::AbstractQuasiVector) = a.F \ view(b, a.map)
\(a::MappedFactorization, b::AbstractVector) = a.F \ b
\(a::MappedFactorization, b::AbstractQuasiMatrix) = a.F \ view(b, a.map, :)


function invmap end

Expand Down Expand Up @@ -268,6 +276,9 @@ function broadcasted(::LazyQuasiArrayStyle{1}, ::typeof(*), a::Expansion, f::Exp
end


_function_mult_broadcasted(_, _, a, B) = Base.Broadcast.Broadcasted{LazyQuasiArrayStyle{2}}(*, (a, B))
broadcasted(::LazyQuasiArrayStyle{2}, ::typeof(*), a::Expansion, B::AbstractQuasiMatrix) = _function_mult_broadcasted(MemoryLayout(a), MemoryLayout(B), a, B)

@eval function ==(f::Expansion, g::Expansion)
S,c = arguments(f)
T,d = arguments(g)
Expand Down Expand Up @@ -351,6 +362,11 @@ function demap(V::SubQuasiArray{<:Any,2})
kr, jr = parentindices(V)
demap(parent(V)[kr,:])[:,jr]
end
function demap(wB::ApplyQuasiArray{<:Any,N,typeof(*)}) where N
a = arguments(wB)
*(demap(first(a)), tail(a)...)
end


basismap(x::SubQuasiArray) = parentindices(x)[1]
basismap(x::BroadcastQuasiArray) = basismap(x.args[1])
Expand Down
22 changes: 10 additions & 12 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -97,13 +97,8 @@ end
@test f[2.1] 2

@test @inferred(H'H) == @inferred(materialize(applied(*,H',H))) == Eye(2)
if VERSION < v"1.6-"
@test summary(f) == "(Spline{0,Float64,Array{$Int,1}}) * (2-element Array{$Int,1})"
@test stringmime("text/plain", f) == "Spline{0,Float64,Array{$Int,1}} * [1, 2]"
else
@test summary(f) == "(HeavisideSpline{Float64, Vector{$Int}}) * (2-element Vector{$Int})"
@test stringmime("text/plain", f) == "HeavisideSpline{Float64, Vector{$Int}} * [1, 2]"
end
@test summary(f) == "(HeavisideSpline{Float64, Vector{$Int}}) * (2-element Vector{$Int})"
@test stringmime("text/plain", f) == "HeavisideSpline{Float64, Vector{$Int}} * [1, 2]"
end

@testset "LinearSpline" begin
Expand Down Expand Up @@ -442,6 +437,13 @@ end
@testset "vec demap" begin
@test L[y,:] \ exp.(axes(L,1))[y] L[y,:] \ exp.(y) factorize(L[y,:]) \ exp.(y)
@test ContinuumArrays.demap(view(axes(L,1),y)) == axes(L,1)

@test L[y,:] \ (y .* exp.(y)) L[y,:] \ BroadcastQuasiVector(y -> y*exp(y), y)
@test L[y,:] \ (y .* L[y,1:3]) [L[y,:]\(y .* L[y,1]) L[y,:]\(y .* L[y,2]) L[y,:]\(y .* L[y,3])]

c = randn(size(L,2))
@test L[y,:] \ (L[y,:] * c) c
@test ContinuumArrays.demap(L[y,:] * c) == L*c
end
end

Expand All @@ -457,11 +459,7 @@ end
H = HeavisideSpline([1,2,3,6])
B = H[5x .+ 1,:]
u = H * [1,2,3]
if VERSION < v"1.6-"
@test stringmime("text/plain", B) == "Spline{0,Float64,Array{$Int,1}} affine mapped to 0..1"
else
@test stringmime("text/plain", B) == "HeavisideSpline{Float64, Vector{$Int}} affine mapped to 0..1"
end
@test stringmime("text/plain", B) == "HeavisideSpline{Float64, Vector{$Int}} affine mapped to 0..1"
end
end

Expand Down

2 comments on commit 05df318

@dlfivefifty
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JuliaRegistrator
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Registration pull request created: JuliaRegistries/General/38540

After the above pull request is merged, it is recommended that a tag is created on this repository for the registered package version.

This will be done automatically if the Julia TagBot GitHub Action is installed, or can be done manually through the github interface, or via:

git tag -a v0.8.1 -m "<description of version>" 05df3189a018a3828e43c1a346ede172df428512
git push origin v0.8.1

Please sign in to comment.