Skip to content

Commit

Permalink
numbers as a map
Browse files Browse the repository at this point in the history
  • Loading branch information
daanhb committed Jan 25, 2025
1 parent b3d9f3d commit a8db302
Show file tree
Hide file tree
Showing 6 changed files with 75 additions and 29 deletions.
2 changes: 1 addition & 1 deletion docs/make.jl
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,5 @@ makedocs(;
)

deploydocs(;
repo="github.com/JuliaApproximation/FunctionMaps.jl.git", devbranch="master",
repo="github.com/JuliaApproximation/FunctionMaps.jl.git", devbranch="main",
)
2 changes: 2 additions & 0 deletions src/generic/interface.jl
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ MapStyle(::Type{<:Map}) = IsMap()
functionmap(m)
Return a map associated with the object `m`.
The result need not have type `Map`, but its `MapStyle` is `IsMap`.
"""
functionmap(m::Map) = m

Expand Down
84 changes: 58 additions & 26 deletions src/types/affine.jl
Original file line number Diff line number Diff line change
Expand Up @@ -292,32 +292,6 @@ StaticLinearMap{T,N,M}(A::AbstractMatrix) where {T,N,M} =
convert(::Type{Map{SVector{N,T}}}, m::VectorLinearMap) where {N,T} = StaticLinearMap{T,N,N}(m.A)


# Implement the interface for abstract arrays,
# representing the linear map x->A*x
MapStyle(A::AbstractArray) = IsMap()

Map(A::AbstractArray) = LinearMap(A)
Map{T}(A::AbstractArray) where T = LinearMap{T}(A)

domaintype(A::AbstractArray) = domaintype(Map(A))

applymap(A::AbstractArray, x) = A*x
mapsize(A::AbstractArray) = size(A)

islinearmap(A::AbstractArray) = true
isaffinemap(A::AbstractArray) = true
affinematrix(A::AbstractArray) = A
affinevector(A::AbstractArray) = zerovector(A)

inverse(A::AbstractMatrix) = inv(A)
inverse(A::AbstractMatrix, x) = A \ x

jacobian(A::AbstractMatrix) = ConstantMap{glm_domaintype(A)}(A)
jacobian(A::AbstractMatrix, x) = A

canonicalmap(A::AbstractArray) = Map(A)
canonicalmap(::Equal, A::AbstractArray) = Map(A)




Expand Down Expand Up @@ -618,10 +592,68 @@ convert(::Type{Map{SVector{N,T}}}, m::VectorAffineMap) where {N,T} =
StaticAffineMap{T,N}(m.A, m.b)


##############################
# Numbers and arrays as a map
##############################

# Arrays represent the linear map A*x
MapStyle(::Type{<:AbstractArray}) = IsMap()

Map(A::AbstractArray) = LinearMap(A)
Map{T}(A::AbstractArray) where T = LinearMap{T}(A)

domaintype(A::AbstractArray) = domaintype(Map(A))

applymap(A::AbstractArray, x) = A*x
mapsize(A::AbstractArray) = size(A)

islinearmap(A::AbstractArray) = true
isaffinemap(A::AbstractArray) = true
affinematrix(A::AbstractArray) = A
affinevector(A::AbstractArray) = zerovector(A)

inverse(A::AbstractMatrix) = inv(A)
inverse(A::AbstractMatrix, x) = A \ x

jacobian(A::AbstractMatrix) = ConstantMap{glm_domaintype(A)}(A)
jacobian(A::AbstractMatrix, x) = A

canonicalmap(A::AbstractArray) = Map(A)
canonicalmap(::Equal, A::AbstractArray) = Map(A)

# Numbers represent the linear map a*x

MapStyle(::Type{<:Number}) = IsMap()

applymap(a::Number, x) = a*x

Map(a::Number) = LinearMap(a)
Map{T}(a::Number) where T = LinearMap{T}(a)
domaintype(a::Number) = typeof(a)

mapsize(a::Number) = ()

islinearmap(a::Number) = true
isaffinemap(a::Number) = true
affinematrix(a::Number) = a
affinevector(a::Number) = zero(a)

inverse(a::Number) = inv(a)
inverse(a::Number, x) = a \ x

jacobian(a::Number) = ConstantMap(a)
jacobian(a::Number, x) = a

canonicalmap(a::Number) = Map(a)
canonicalmap(::Equal, a::Number) = Map(a)


###########################
# Uniform scaling as a map
###########################

MapStyle(::Type{<:UniformScaling}) = IsMap()

convert(::Type{Map}, A::UniformScaling) = GenericLinearMap{Vector{Any}}(A)
convert(::Type{Map{T}}, A::UniformScaling) where {T} = GenericLinearMap{T}(A)

Expand Down
1 change: 1 addition & 0 deletions src/util/common.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
isrealtype(::Type{<:Real}) = true
isrealtype(::Type{<:Complex}) = false
isrealtype(::Type{T}) where {T} = isrealtype(eltype(T))
isrealtype(::Type{Any}) = false

const StaticTypes = Union{Number,<:StaticVector{N} where N,<:NTuple{N,Any} where N}

Expand Down
11 changes: 11 additions & 0 deletions test/test_common.jl
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,15 @@ function test_numtype()
@test promote_numtype(2, 3.0+im, big(4)) isa Tuple{Complex{BigFloat},Complex{BigFloat},Complex{BigFloat}}
end

using FunctionMaps: isrealtype

function test_realtype()
@test isrealtype(Any) == false
@test isrealtype(Int) == true
@test isrealtype(ComplexF64) == false
@test isrealtype(Matrix{Float64}) == true
end

@testset "common functionality" begin
@testset "dimension" begin
test_dimension()
Expand All @@ -94,4 +103,6 @@ end
@testset "numtype" begin
test_numtype()
end

test_realtype()
end
4 changes: 2 additions & 2 deletions test/test_interface.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ struct MySimpleMap end
FunctionMaps.MapStyle(::Type{MySimpleMap}) = IsMap()

@testset "map interface" begin
@test MapStyle(2.0) isa NotMap
@test_throws ArgumentError checkmap((5,)) # a tuple is not a map
@test MapStyle(2.0) isa IsMap
@test MapStyle(2.0) == MapStyle(typeof(2.0))
@test_throws ArgumentError checkmap(2.0)
m = LinearMap(2)
@test MapStyle(m) isa IsMap
@test functionmap(m) === m
Expand Down

0 comments on commit a8db302

Please sign in to comment.