diff --git a/Project.toml b/Project.toml index b581539..2bea614 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "ArrayLayouts" uuid = "4c555306-a7a7-4459-81d9-ec55ddd5c99a" authors = ["Sheehan Olver "] -version = "0.5.0" +version = "0.5.1" [deps] Compat = "34da2185-b29b-5c13-b0c7-acf172513d20" diff --git a/src/mul.jl b/src/mul.jl index 47d2667..ff6df80 100644 --- a/src/mul.jl +++ b/src/mul.jl @@ -254,8 +254,26 @@ dot(a, b) = materialize(Dot(a, b)) @inline LinearAlgebra.dot(a::LayoutArray, b::SubArray{<:Any,N,<:LayoutArray}) where N = dot(a,b) @inline LinearAlgebra.dot(a::SubArray{<:Any,N,<:LayoutArray}, b::SubArray{<:Any,N,<:LayoutArray}) where N = dot(a,b) -# Temporary until layout 3-arg dot is added. +# Temporary until layout 3-arg dot is added. # We go to generic fallback as layout-arrays are structured dot(x, A, y) = dot(x, mul(A, y)) LinearAlgebra.dot(x::AbstractVector, A::LayoutMatrix, y::AbstractVector) = dot(x, A, y) LinearAlgebra.dot(x::AbstractVector, A::Symmetric{<:Real,<:LayoutMatrix}, y::AbstractVector) = dot(x, A, y) + + + +# allow overloading for infinite or lazy case +@inline _power_by_squaring(_, _, A, p) = Base.invoke(Base.power_by_squaring, Tuple{AbstractMatrix,Integer}, A, p) +@inline _apply(_, _, op, A::AbstractMatrix, Λ::UniformScaling) = Base.invoke(op, Tuple{AbstractMatrix,UniformScaling}, A, Λ) +@inline _apply(_, _, op, Λ::UniformScaling, A::AbstractMatrix) = Base.invoke(op, Tuple{UniformScaling,AbstractMatrix}, Λ, A) + +for Typ in (:LayoutMatrix, :(Symmetric{<:Any,<:LayoutMatrix}), :(Hermitian{<:Any,<:LayoutMatrix}), + :(Adjoint{<:Any,<:LayoutMatrix}), :(Transpose{<:Any,<:LayoutMatrix})) + @eval begin + @inline Base.power_by_squaring(A::$Typ, p::Integer) = _power_by_squaring(MemoryLayout(A), size(A), A, p) + @inline +(A::$Typ, Λ::UniformScaling) = _apply(MemoryLayout(A), size(A), +, A, Λ) + @inline +(Λ::UniformScaling, A::$Typ) = _apply(MemoryLayout(A), size(A), +, Λ, A) + @inline -(A::$Typ, Λ::UniformScaling) = _apply(MemoryLayout(A), size(A), -, A, Λ) + @inline -(Λ::UniformScaling, A::$Typ) = _apply(MemoryLayout(A), size(A), -, Λ, A) + end +end \ No newline at end of file diff --git a/test/runtests.jl b/test/runtests.jl index 5433960..1d34941 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -177,6 +177,17 @@ MemoryLayout(::Type{MyVector}) = DenseColumnMajor() @test ArrayLayouts.ldiv!(2, Hermitian(copy(C))) == ArrayLayouts.rdiv!(Hermitian(copy(C)), 2) == 2\Hermitian(C) end end + + @testset "pow/I" begin + A = randn(2,2) + B = MyMatrix(A) + @test B^2 ≈ A^2 + @test B^2.3 ≈ A^2.3 + @test B^(-1) ≈ inv(A) + @test B + I ≈ I + B ≈ A + I + @test B - I ≈ A - I + @test I - B ≈ I - B + end end struct MyUpperTriangular{T} <: AbstractMatrix{T}