From 1f151e70b7b1e8068ee67a6beac868499e25227a Mon Sep 17 00:00:00 2001 From: Daniel Karrasch Date: Sun, 25 Aug 2019 18:44:31 +0200 Subject: [PATCH 1/4] composition with boolean UniformScaling, minor code polish, use unicode --- src/composition.jl | 46 ++++++++++++++++++++++++---------------------- 1 file changed, 24 insertions(+), 22 deletions(-) diff --git a/src/composition.jl b/src/composition.jl index 4bc00225..8546bbb2 100644 --- a/src/composition.jl +++ b/src/composition.jl @@ -40,11 +40,11 @@ end # scalar multiplication and division function Base.:(*)(α::Number, A::LinearMap) - T = promote_type(eltype(α), eltype(A)) + T = promote_type(typeof(α), eltype(A)) return CompositeMap{T}(tuple(A, UniformScalingMap(α, size(A, 1)))) end function Base.:(*)(α::Number, A::CompositeMap) - T = promote_type(eltype(α), eltype(A)) + T = promote_type(typeof(α), eltype(A)) Alast = last(A.maps) if Alast isa UniformScalingMap return CompositeMap{T}(tuple(Base.front(A.maps)..., UniformScalingMap(α * Alast.λ, size(Alast, 1)))) @@ -53,11 +53,11 @@ function Base.:(*)(α::Number, A::CompositeMap) end end function Base.:(*)(A::LinearMap, α::Number) - T = promote_type(eltype(α), eltype(A)) + T = promote_type(typeof(α), eltype(A)) return CompositeMap{T}(tuple(UniformScalingMap(α, size(A, 2)), A)) end function Base.:(*)(A::CompositeMap, α::Number) - T = promote_type(eltype(α), eltype(A)) + T = promote_type(typeof(α), eltype(A)) Afirst = first(A.maps) if Afirst isa UniformScalingMap return CompositeMap{T}(tuple(UniformScalingMap(Afirst.λ * α, size(Afirst, 1)), Base.tail(A.maps)...)) @@ -70,28 +70,30 @@ Base.:(/)(A::LinearMap, α::Number) = A * inv(α) Base.:(-)(A::LinearMap) = -1 * A # composition of linear maps -function Base.:(*)(A1::CompositeMap, A2::CompositeMap) - size(A1, 2) == size(A2, 1) || throw(DimensionMismatch("*")) - T = promote_type(eltype(A1), eltype(A2)) - return CompositeMap{T}(tuple(A2.maps..., A1.maps...)) +function Base.:(*)(A₁::CompositeMap, A₂::CompositeMap) + size(A₁, 2) == size(A₂, 1) || throw(DimensionMismatch("*")) + T = promote_type(eltype(A₁), eltype(A₂)) + return CompositeMap{T}(tuple(A₂.maps..., A₁.maps...)) end -function Base.:(*)(A1::LinearMap, A2::CompositeMap) - size(A1, 2) == size(A2, 1) || throw(DimensionMismatch("*")) - T = promote_type(eltype(A1), eltype(A2)) - return CompositeMap{T}(tuple(A2.maps..., A1)) +function Base.:(*)(A₁::LinearMap, A₂::CompositeMap) + size(A₁, 2) == size(A₂, 1) || throw(DimensionMismatch("*")) + T = promote_type(eltype(A₁), eltype(A₂)) + return CompositeMap{T}(tuple(A₂.maps..., A₁)) end -function Base.:(*)(A1::CompositeMap, A2::LinearMap) - size(A1, 2) == size(A2, 1) || throw(DimensionMismatch("*")) - T = promote_type(eltype(A1), eltype(A2)) - return CompositeMap{T}(tuple(A2, A1.maps...)) +function Base.:(*)(A₁::CompositeMap, A₂::LinearMap) + size(A₁, 2) == size(A₂, 1) || throw(DimensionMismatch("*")) + T = promote_type(eltype(A₁), eltype(A₂)) + return CompositeMap{T}(tuple(A₂, A₁.maps...)) end -function Base.:(*)(A1::LinearMap, A2::LinearMap) - size(A1, 2) == size(A2, 1) || throw(DimensionMismatch("*")) - T = promote_type(eltype(A1),eltype(A2)) - return CompositeMap{T}(tuple(A2, A1)) +function Base.:(*)(A₁::LinearMap, A₂::LinearMap) + size(A₁, 2) == size(A₂, 1) || throw(DimensionMismatch("*")) + T = promote_type(eltype(A₁), eltype(A₂)) + return CompositeMap{T}(tuple(A₂, A₁)) end -Base.:(*)(A1::LinearMap, A2::UniformScaling{T}) where {T} = A1 * A2[1,1] -Base.:(*)(A1::UniformScaling{T}, A2::LinearMap) where {T} = A1[1,1] * A2 +Base.:(*)(A₁::LinearMap, A₂::UniformScaling) = A₁ * A₂.λ +Base.:(*)(A₁::LinearMap, A₂::UniformScaling{Bool}) = A₂.λ ? A₁ : A₁ * A₂.λ +Base.:(*)(A₁::UniformScaling, A₂::LinearMap) = A₁.λ * A₂ +Base.:(*)(A₁::UniformScaling{Bool}, A₂::LinearMap) = A₁.λ ? A₂ : A₁.λ * A₂ # special transposition behavior LinearAlgebra.transpose(A::CompositeMap{T}) where {T} = CompositeMap{T}(map(transpose, reverse(A.maps))) From 70c146e653495afc0a5d62b4dd1f7f5f34614668 Mon Sep 17 00:00:00 2001 From: Daniel Karrasch Date: Tue, 27 Aug 2019 10:44:10 +0200 Subject: [PATCH 2/4] use unicode throughout --- src/linearcombination.jl | 28 ++++++++++++++-------------- src/uniformscalingmap.jl | 8 ++++---- src/wrappedmap.jl | 12 ++++++------ 3 files changed, 24 insertions(+), 24 deletions(-) diff --git a/src/linearcombination.jl b/src/linearcombination.jl index a378baed..096ca13f 100644 --- a/src/linearcombination.jl +++ b/src/linearcombination.jl @@ -20,23 +20,23 @@ LinearAlgebra.ishermitian(A::LinearCombination) = all(ishermitian, A.maps) # suf LinearAlgebra.isposdef(A::LinearCombination) = all(isposdef, A.maps) # sufficient but not necessary # adding linear maps -function Base.:(+)(A1::LinearCombination, A2::LinearCombination) - size(A1) == size(A2) || throw(DimensionMismatch("+")) - T = promote_type(eltype(A1), eltype(A2)) - return LinearCombination{T}(tuple(A1.maps..., A2.maps...)) +function Base.:(+)(A₁::LinearCombination, A₂::LinearCombination) + size(A₁) == size(A₂) || throw(DimensionMismatch("+")) + T = promote_type(eltype(A₁), eltype(A₂)) + return LinearCombination{T}(tuple(A₁.maps..., A₂.maps...)) end -function Base.:(+)(A1::LinearMap, A2::LinearCombination) - size(A1) == size(A2) || throw(DimensionMismatch("+")) - T = promote_type(eltype(A1), eltype(A2)) - return LinearCombination{T}(tuple(A1, A2.maps...)) +function Base.:(+)(A₁::LinearMap, A₂::LinearCombination) + size(A₁) == size(A₂) || throw(DimensionMismatch("+")) + T = promote_type(eltype(A₁), eltype(A₂)) + return LinearCombination{T}(tuple(A₁, A₂.maps...)) end -Base.:(+)(A1::LinearCombination, A2::LinearMap) = +(A2, A1) -function Base.:(+)(A1::LinearMap, A2::LinearMap) - size(A1)==size(A2) || throw(DimensionMismatch("+")) - T = promote_type(eltype(A1), eltype(A2)) - return LinearCombination{T}(tuple(A1, A2)) +Base.:(+)(A₁::LinearCombination, A₂::LinearMap) = +(A₂, A₁) +function Base.:(+)(A₁::LinearMap, A₂::LinearMap) + size(A₁) == size(A₂) || throw(DimensionMismatch("+")) + T = promote_type(eltype(A₁), eltype(A₂)) + return LinearCombination{T}(tuple(A₁, A₂)) end -Base.:(-)(A1::LinearMap, A2::LinearMap) = +(A1, -A2) +Base.:(-)(A₁::LinearMap, A₂::LinearMap) = +(A₁, -A₂) # comparison of LinearCombination objects, sufficient but not necessary Base.:(==)(A::LinearCombination, B::LinearCombination) = (eltype(A) == eltype(B) && A.maps == B.maps) diff --git a/src/uniformscalingmap.jl b/src/uniformscalingmap.jl index c46bb4ec..046d0243 100644 --- a/src/uniformscalingmap.jl +++ b/src/uniformscalingmap.jl @@ -70,7 +70,7 @@ function LinearAlgebra.mul!(y::AbstractVector, J::UniformScalingMap{T}, x::Abstr end # combine LinearMap and UniformScaling objects in linear combinations -Base.:(+)(A1::LinearMap, A2::UniformScaling) = A1 + UniformScalingMap(A2.λ, size(A1, 1)) -Base.:(+)(A1::UniformScaling, A2::LinearMap) = UniformScalingMap(A1.λ, size(A2, 1)) + A2 -Base.:(-)(A1::LinearMap, A2::UniformScaling) = A1 - UniformScalingMap(A2.λ, size(A1, 1)) -Base.:(-)(A1::UniformScaling, A2::LinearMap) = UniformScalingMap(A1.λ, size(A2, 1)) - A2 +Base.:(+)(A₁::LinearMap, A₂::UniformScaling) = A₁ + UniformScalingMap(A₂.λ, size(A₁, 1)) +Base.:(+)(A₁::UniformScaling, A₂::LinearMap) = UniformScalingMap(A₁.λ, size(A₂, 1)) + A₂ +Base.:(-)(A₁::LinearMap, A₂::UniformScaling) = A₁ - UniformScalingMap(A₂.λ, size(A₁, 1)) +Base.:(-)(A₁::UniformScaling, A₂::LinearMap) = UniformScalingMap(A₁.λ, size(A₂, 1)) - A₂ diff --git a/src/wrappedmap.jl b/src/wrappedmap.jl index a2addc78..7ba88424 100644 --- a/src/wrappedmap.jl +++ b/src/wrappedmap.jl @@ -34,10 +34,10 @@ Ac_mul_B!(y::AbstractVector, A::WrappedMap, x::AbstractVector) = ishermitian(A) ? A_mul_B!(y, A.lmap, x) : Ac_mul_B!(y, A.lmap, x) # combine LinearMap and Matrix objects: linear combinations and map composition -Base.:(+)(A1::LinearMap, A2::AbstractMatrix) = +(A1, WrappedMap(A2)) -Base.:(+)(A1::AbstractMatrix, A2::LinearMap) = +(WrappedMap(A1), A2) -Base.:(-)(A1::LinearMap, A2::AbstractMatrix) = -(A1, WrappedMap(A2)) -Base.:(-)(A1::AbstractMatrix, A2::LinearMap) = -(WrappedMap(A1), A2) +Base.:(+)(A₁::LinearMap, A₂::AbstractMatrix) = +(A₁, WrappedMap(A₂)) +Base.:(+)(A₁::AbstractMatrix, A₂::LinearMap) = +(WrappedMap(A₁), A₂) +Base.:(-)(A₁::LinearMap, A₂::AbstractMatrix) = -(A₁, WrappedMap(A₂)) +Base.:(-)(A₁::AbstractMatrix, A₂::LinearMap) = -(WrappedMap(A₁), A₂) -Base.:(*)(A1::LinearMap, A2::AbstractMatrix) = *(A1, WrappedMap(A2)) -Base.:(*)(A1::AbstractMatrix, A2::LinearMap) = *(WrappedMap(A1), A2) +Base.:(*)(A₁::LinearMap, A₂::AbstractMatrix) = *(A₁, WrappedMap(A₂)) +Base.:(*)(A₁::AbstractMatrix, A₂::LinearMap) = *(WrappedMap(A₁), A₂) From 88792be8a3b0790da0a748eeb2189fbb0bbd2533 Mon Sep 17 00:00:00 2001 From: Daniel Karrasch Date: Wed, 28 Aug 2019 09:53:43 +0200 Subject: [PATCH 3/4] use shorthand notation --- src/blockmap.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/blockmap.jl b/src/blockmap.jl index 8e9deda4..21b55b59 100644 --- a/src/blockmap.jl +++ b/src/blockmap.jl @@ -172,7 +172,7 @@ promote_to_lmaps(n, k, dim, A) = (promote_to_lmaps_(n[k], dim, A),) function isblocksquare(A::BlockMap) rows = A.rows N = length(rows) - return all(r -> r == N, rows) + return all(==(N), rows) end # the following rules are sufficient but not necessary From 22c29e6ca21889cb27801fccca56b0476dc30d11 Mon Sep 17 00:00:00 2001 From: Daniel Karrasch Date: Wed, 28 Aug 2019 09:58:40 +0200 Subject: [PATCH 4/4] follow Julia style guide --- src/composition.jl | 8 +++----- src/linearcombination.jl | 4 ++-- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/composition.jl b/src/composition.jl index 8546bbb2..f7df3a14 100644 --- a/src/composition.jl +++ b/src/composition.jl @@ -2,10 +2,10 @@ struct CompositeMap{T, As<:Tuple{Vararg{LinearMap}}} <: LinearMap{T} maps::As # stored in order of application to vector function CompositeMap{T, As}(maps::As) where {T, As} N = length(maps) - for n = 2:N + for n in 2:N size(maps[n], 2) == size(maps[n-1], 1) || throw(DimensionMismatch("CompositeMap")) end - for n = 1:N + for n in 1:N promote_type(T, eltype(maps[n])) == T || throw(InexactError()) end new{T, As}(maps) @@ -91,9 +91,7 @@ function Base.:(*)(A₁::LinearMap, A₂::LinearMap) return CompositeMap{T}(tuple(A₂, A₁)) end Base.:(*)(A₁::LinearMap, A₂::UniformScaling) = A₁ * A₂.λ -Base.:(*)(A₁::LinearMap, A₂::UniformScaling{Bool}) = A₂.λ ? A₁ : A₁ * A₂.λ Base.:(*)(A₁::UniformScaling, A₂::LinearMap) = A₁.λ * A₂ -Base.:(*)(A₁::UniformScaling{Bool}, A₂::LinearMap) = A₁.λ ? A₂ : A₁.λ * A₂ # special transposition behavior LinearAlgebra.transpose(A::CompositeMap{T}) where {T} = CompositeMap{T}(map(transpose, reverse(A.maps))) @@ -116,7 +114,7 @@ function A_mul_B!(y::AbstractVector, A::CompositeMap, x::AbstractVector) if N>2 dest = Array{T}(undef, size(A.maps[2], 1)) end - for n=2:N-1 + for n in 2:N-1 try resize!(dest, size(A.maps[n], 1)) catch err diff --git a/src/linearcombination.jl b/src/linearcombination.jl index 096ca13f..24a7b3b8 100644 --- a/src/linearcombination.jl +++ b/src/linearcombination.jl @@ -3,7 +3,7 @@ struct LinearCombination{T, As<:Tuple{Vararg{LinearMap}}} <: LinearMap{T} function LinearCombination{T, As}(maps::As) where {T, As} N = length(maps) sz = size(maps[1]) - for n = 1:N + for n in 1:N size(maps[n]) == sz || throw(DimensionMismatch("LinearCombination")) promote_type(T, eltype(maps[n])) == T || throw(InexactError()) end @@ -52,7 +52,7 @@ function A_mul_B!(y::AbstractVector, A::LinearCombination, x::AbstractVector) l = length(A.maps) if l>1 z = similar(y) - for n=2:l + for n in 2:l A_mul_B!(z, A.maps[n], x) y .+= z end