Skip to content

Commit

Permalink
fixes for 0.7
Browse files Browse the repository at this point in the history
  • Loading branch information
fredrikekre committed Jun 28, 2018
1 parent 4b1afb6 commit 08053ba
Show file tree
Hide file tree
Showing 51 changed files with 429 additions and 719 deletions.
3 changes: 1 addition & 2 deletions REQUIRE
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
julia 0.6.0
Compat 0.66
julia 0.7-alpha
2 changes: 1 addition & 1 deletion docs/src/pages/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ the dimensions of a static array. An array `sa::SA` of size `(dims...)` is
associated with `Size{(dims...)}()`. The following are equivalent (`@pure`)
constructors:
```julia
Size{(dims...)}()
Size{(dims...,)}()
Size(dims...)
Size(sa::StaticArray)
Size(SA) # SA <: StaticArray
Expand Down
2 changes: 1 addition & 1 deletion perf/benchmark-qr.jl
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
using StaticArrays
using BenchmarkTools, Compat
using BenchmarkTools

a = m = 0
for K = 1:22
Expand Down
2 changes: 1 addition & 1 deletion perf/benchmark_matrix_ops.jl
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using StaticArrays, BenchmarkTools, DataFrames, DataStructures

Nmax = 20
unary = (det, inv, expm)
unary = (det, inv, exp)
binary = (\,)

data = OrderedDict{Symbol,Any}()
Expand Down
18 changes: 7 additions & 11 deletions src/SDiagonal.jl
Original file line number Diff line number Diff line change
Expand Up @@ -85,18 +85,14 @@ eye(::Type{SDiagonal{N,T}}) where {N,T} = SDiagonal(ones(SVector{N,T}))
one(::Type{SDiagonal{N,T}}) where {N,T} = SDiagonal(ones(SVector{N,T}))
one(::SDiagonal{N,T}) where {N,T} = SDiagonal(ones(SVector{N,T}))
Base.zero(::SDiagonal{N,T}) where {N,T} = SDiagonal(zeros(SVector{N,T}))
if VERSION < v"0.7-"
expm(D::SDiagonal) = SDiagonal(exp.(D.diag))
logm(D::SDiagonal) = SDiagonal(log.(D.diag))
sqrtm(D::SDiagonal) = SDiagonal(sqrt.(D.diag))
else
exp(D::SDiagonal) = SDiagonal(exp.(D.diag))
log(D::SDiagonal) = SDiagonal(log.(D.diag))
sqrt(D::SDiagonal) = SDiagonal(sqrt.(D.diag))
exp(D::SDiagonal) = SDiagonal(exp.(D.diag))
log(D::SDiagonal) = SDiagonal(log.(D.diag))
sqrt(D::SDiagonal) = SDiagonal(sqrt.(D.diag))
function LinearAlgebra.cholesky(D::SDiagonal)
any(x -> x < 0, D.diag) && throw(LinearAlgebra.PosDefException(1))
C = sqrt.(D.diag)
return Cholesky(SDiagonal(C), 'U', 0)
end
LinearAlgebra.chol(D::SDiagonal) = SDiagonal(chol.(D.diag))
LinearAlgebra.chol(D::SDiagonal{N, T}) where {N, T <: Number} = SDiagonal(sqrt.(D.diag))
LinearAlgebra._chol!(D::SDiagonal, ::Type{UpperTriangular}) = chol(D)

\(D::SDiagonal, B::StaticMatrix) = scalem(1 ./ D.diag, B)
/(B::StaticMatrix, D::SDiagonal) = scalem(1 ./ D.diag, B)
Expand Down
49 changes: 12 additions & 37 deletions src/StaticArrays.jl
Original file line number Diff line number Diff line change
Expand Up @@ -10,42 +10,17 @@ import Base: getindex, setindex!, size, similar, vec, show, length, convert, pro
iszero, sum, prod, count, any, all, minimum, maximum, extrema, mean,
copy, read, read!, write

if VERSION < v"0.7-"
using Compat

using Base.Random
import Base: rand, randn, randexp, rand!, randn!, randexp!
using Core.Inference.return_type

import Base.LinAlg: transpose, ctranspose, eye, vecdot, eig, eigvals, eigfact, expm,
logm, sqrtm, lyap, trace, kron, diag, vecnorm, norm, dot, diagm, lu,
svd, svdvals, svdfact, factorize, ishermitian, issymmetric,
isposdef, normalize, normalize!, Eigen, det, logdet, cross, diff, qr
const LinearAlgebra = Base.LinAlg

const TransposeVector{T, V<:AbstractVector{T}} = RowVector{T, V}
const AdjointVector{T, V<:AbstractVector{T}} = RowVector{T, ConjVector{T, V}}

const adjoint = ctranspose
const tr = trace
else
using Compat

using Random
import Random: rand, randn, randexp, rand!, randn!, randexp!
using Core.Compiler: return_type

import Base: sqrt, exp, log

using LinearAlgebra
import LinearAlgebra: transpose, adjoint, eye, vecdot, eig, eigvals, eigfact, lyap, tr,
kron, diag, vecnorm, norm, dot, diagm, lu, svd, svdvals, svdfact,
factorize, ishermitian, issymmetric, isposdef, normalize,
normalize!, Eigen, det, logdet, cross, diff, qr

const TransposeVector{T, V<:AbstractVector{T}} = Transpose{T, V}
const AdjointVector{T, V<:AbstractVector{T}} = Adjoint{T, V}
end
using Random
import Random: rand, randn, randexp, rand!, randn!, randexp!
using Core.Compiler: return_type
import Base: sqrt, exp, log
using LinearAlgebra
import LinearAlgebra: transpose, adjoint, eye, vecdot, eigvals, eigen, lyap, tr,
kron, diag, norm, dot, diagm, lu, svd, svdvals, svdfact,
factorize, ishermitian, issymmetric, isposdef, normalize,
normalize!, Eigen, det, logdet, cross, diff, qr
const TransposeVector{T, V<:AbstractVector{T}} = Transpose{T, V}
const AdjointVector{T, V<:AbstractVector{T}} = Adjoint{T, V}

export StaticScalar, StaticArray, StaticVector, StaticMatrix
export Scalar, SArray, SVector, SMatrix
Expand All @@ -60,7 +35,7 @@ export @SVector, @SMatrix, @SArray
export @MVector, @MMatrix, @MArray

export similar_type
export push, pop, shift, unshift, insert, deleteat, setindex
export push, pop, pushfirst, popfirst, insert, deleteat, setindex

const _module_arg = isdefined(Base, Symbol("@__MODULE__"))

Expand Down
43 changes: 5 additions & 38 deletions src/abstractarray.jl
Original file line number Diff line number Diff line change
Expand Up @@ -125,42 +125,9 @@ reshape(a::Array, s::Size{S}) where {S} = s(a)

# TODO permutedims?

# TODO perhaps could move `Symmetric`, etc into seperate files.

# This is used in Base.LinAlg quite a lot, and it impacts type stability
# since some functions like expm() branch on a check for Hermitian or Symmetric
# TODO much more work on type stability. Base functions are using similar() with
# size, which poses difficulties!!
@inline Base.full(sym::Symmetric{T,SM}) where {T,SM <: StaticMatrix} = _full(Size(SM), sym)

@generated function _full(::Size{S}, sym::Symmetric{T,SM}) where {S, T, SM <: StaticMatrix}
exprs_up = [i <= j ? :(m[$(LinearIndices(S)[i, j])]) : :(m[$(LinearIndices(S)[j, i])]) for i = 1:S[1], j=1:S[2]]
exprs_lo = [i >= j ? :(m[$(LinearIndices(S)[i, j])]) : :(m[$(LinearIndices(S)[j, i])]) for i = 1:S[1], j=1:S[2]]

return quote
@_inline_meta
m = sym.data
if sym.uplo == 'U'
@inbounds return SM(tuple($(exprs_up...)))
else
@inbounds return SM(tuple($(exprs_lo...)))
end
end
end

@inline Base.full(herm::Hermitian{T,SM}) where {T,SM <: StaticMatrix} = _full(Size(SM), herm)

@generated function _full(::Size{S}, herm::Hermitian{T,SM}) where {S, T, SM <: StaticMatrix}
exprs_up = [i <= j ? :(m[$(LinearIndices(S)[i, j])]) : :(conj(m[$(LinearIndices(S)[j, i])])) for i = 1:S[1], j=1:S[2]]
exprs_lo = [i >= j ? :(m[$(LinearIndices(S)[i, j])]) : :(conj(m[$(LinearIndices(S)[j, i])])) for i = 1:S[1], j=1:S[2]]

return quote
@_inline_meta
m = herm.data
if herm.uplo == 'U'
@inbounds return SM(tuple($(exprs_up...)))
else
@inbounds return SM(tuple($(exprs_lo...)))
end
end
# full deprecated in Base
if isdefined(Base, :full)
import Base: full
@deprecate full(sym::Symmetric{T,SM}) where {T,SM <: StaticMatrix} SMatrix(sym)
@deprecate full(herm::Hermitian{T,SM}) where {T,SM <: StaticMatrix} SMatrix(sym)
end
10 changes: 3 additions & 7 deletions src/arraymath.jl
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,9 @@ end

# Also consider randcycle, randperm? Also faster rand!(staticarray, collection)

@static if VERSION >= v"0.7.0-DEV.3406"
using Random: SamplerType
@inline rand(rng::AbstractRNG, ::Type{SA}, dims::Dims) where {SA <: StaticArray} = rand!(rng, Array{SA}(undef, dims), SA)
@inline rand(rng::AbstractRNG, ::SamplerType{SA}) where {SA <: StaticArray} = _rand(rng, Size(SA), SA)
else
@inline rand(rng::AbstractRNG, ::Type{SA}) where {SA <: StaticArray} = _rand(rng, Size(SA), SA)
end
using Random: SamplerType
@inline rand(rng::AbstractRNG, ::Type{SA}, dims::Dims) where {SA <: StaticArray} = rand!(rng, Array{SA}(undef, dims), SA)
@inline rand(rng::AbstractRNG, ::SamplerType{SA}) where {SA <: StaticArray} = _rand(rng, Size(SA), SA)

@generated function _rand(rng::AbstractRNG, ::Size{s}, ::Type{SA}) where {s, SA <: StaticArray}
T = eltype(SA)
Expand Down
120 changes: 32 additions & 88 deletions src/broadcast.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,88 +2,39 @@
## broadcast! ##
################

@static if VERSION < v"0.7.0-DEV.5096"
## Old Broadcast API ##
import Base.Broadcast:
_containertype, promote_containertype, broadcast_indices, containertype,
broadcast_c, broadcast_c!

# Add StaticArray as a new output type in Base.Broadcast promotion machinery.
# This isn't the precise output type, just a placeholder to return from
# promote_containertype, which will control dispatch to our broadcast_c.
_containertype(::Type{<:StaticArray}) = StaticArray
_containertype(::Type{<:RowVector{<:Any,<:StaticVector}}) = StaticArray

# issue #382; prevent infinite recursion in generic broadcast code:
Base.Broadcast.broadcast_indices(::Type{StaticArray}, A) = indices(A)

# With the above, the default promote_containertype gives reasonable defaults:
# StaticArray, StaticArray -> StaticArray
# Array, StaticArray -> Array
#
# We could be more precise about the latter, but this isn't really possible
# without using Array{N} rather than Array in Base's promote_containertype.
#
# Base also has broadcast with tuple + Array, but while implementing this would
# be consistent with Base, it's not exactly clear it's a good idea when you can
# just use an SVector instead?
promote_containertype(::Type{StaticArray}, ::Type{Any}) = StaticArray
promote_containertype(::Type{Any}, ::Type{StaticArray}) = StaticArray

# Override for when output type is deduced to be a StaticArray.
@inline function broadcast_c(f, ::Type{StaticArray}, as...)
argsizes = broadcast_sizes(as...)
destsize = combine_sizes(argsizes)
_broadcast(f, destsize, argsizes, as...)
end

@inline function broadcast_c!(f, ::Type, ::Type{StaticArray}, dest, as...)
argsizes = broadcast_sizes(as...)
destsize = combine_sizes((Size(dest), argsizes...))
Length(destsize) === Length{Dynamic()}() && return broadcast_c!(f, containertype(dest), Array, dest, as...)
_broadcast!(f, destsize, dest, argsizes, as...)
end
else
## New Broadcast API ##
import Base.Broadcast:
BroadcastStyle, AbstractArrayStyle, Broadcasted, DefaultArrayStyle, materialize!

# Add a new BroadcastStyle for StaticArrays, derived from AbstractArrayStyle
# A constructor that changes the style parameter N (array dimension) is also required
struct StaticArrayStyle{N} <: AbstractArrayStyle{N} end
StaticArrayStyle{M}(::Val{N}) where {M,N} = StaticArrayStyle{N}()

BroadcastStyle(::Type{<:StaticArray{<:Any, <:Any, N}}) where {N} = StaticArrayStyle{N}()
BroadcastStyle(::Type{<:Transpose{<:Any, <:StaticArray{<:Any, <:Any, N}}}) where {N} = StaticArrayStyle{N}()
BroadcastStyle(::Type{<:Adjoint{<:Any, <:StaticArray{<:Any, <:Any, N}}}) where {N} = StaticArrayStyle{N}()

# Precedence rules
BroadcastStyle(::StaticArrayStyle{M}, ::DefaultArrayStyle{N}) where {M,N} =
DefaultArrayStyle(Broadcast._max(Val(M), Val(N)))
BroadcastStyle(::StaticArrayStyle{M}, ::DefaultArrayStyle{0}) where {M} =
StaticArrayStyle{M}()

# copy overload
@inline function Base.copy(B::Broadcasted{StaticArrayStyle{M}}) where M
flat = Broadcast.flatten(B); as = flat.args; f = flat.f
argsizes = broadcast_sizes(as...)
destsize = combine_sizes(argsizes)
_broadcast(f, destsize, argsizes, as...)
end

# copyto! overloads
@inline Base.copyto!(dest, B::Broadcasted{<:StaticArrayStyle}) = _copyto!(dest, B)
@inline Base.copyto!(dest::AbstractArray, B::Broadcasted{<:StaticArrayStyle}) = _copyto!(dest, B)
@inline function _copyto!(dest, B::Broadcasted{StaticArrayStyle{M}}) where M
flat = Broadcast.flatten(B); as = flat.args; f = flat.f
argsizes = broadcast_sizes(as...)
destsize = combine_sizes((Size(dest), argsizes...))
if Length(destsize) === Length{Dynamic()}()
# destination dimension cannot be determined statically; fall back to generic broadcast!
return copyto!(dest, convert(Broadcasted{DefaultArrayStyle{M}}, B))
end
_broadcast!(f, destsize, dest, argsizes, as...)
import Base.Broadcast:
BroadcastStyle, AbstractArrayStyle, Broadcasted, DefaultArrayStyle, materialize!
# Add a new BroadcastStyle for StaticArrays, derived from AbstractArrayStyle
# A constructor that changes the style parameter N (array dimension) is also required
struct StaticArrayStyle{N} <: AbstractArrayStyle{N} end
StaticArrayStyle{M}(::Val{N}) where {M,N} = StaticArrayStyle{N}()
BroadcastStyle(::Type{<:StaticArray{<:Any, <:Any, N}}) where {N} = StaticArrayStyle{N}()
BroadcastStyle(::Type{<:Transpose{<:Any, <:StaticArray{<:Any, <:Any, N}}}) where {N} = StaticArrayStyle{N}()
BroadcastStyle(::Type{<:Adjoint{<:Any, <:StaticArray{<:Any, <:Any, N}}}) where {N} = StaticArrayStyle{N}()
# Precedence rules
BroadcastStyle(::StaticArrayStyle{M}, ::DefaultArrayStyle{N}) where {M,N} =
DefaultArrayStyle(Broadcast._max(Val(M), Val(N)))
BroadcastStyle(::StaticArrayStyle{M}, ::DefaultArrayStyle{0}) where {M} =
StaticArrayStyle{M}()
# copy overload
@inline function Base.copy(B::Broadcasted{StaticArrayStyle{M}}) where M
flat = Broadcast.flatten(B); as = flat.args; f = flat.f
argsizes = broadcast_sizes(as...)
destsize = combine_sizes(argsizes)
_broadcast(f, destsize, argsizes, as...)
end
# copyto! overloads
@inline Base.copyto!(dest, B::Broadcasted{<:StaticArrayStyle}) = _copyto!(dest, B)
@inline Base.copyto!(dest::AbstractArray, B::Broadcasted{<:StaticArrayStyle}) = _copyto!(dest, B)
@inline function _copyto!(dest, B::Broadcasted{StaticArrayStyle{M}}) where M
flat = Broadcast.flatten(B); as = flat.args; f = flat.f
argsizes = broadcast_sizes(as...)
destsize = combine_sizes((Size(dest), argsizes...))
if Length(destsize) === Length{Dynamic()}()
# destination dimension cannot be determined statically; fall back to generic broadcast!
return copyto!(dest, convert(Broadcasted{DefaultArrayStyle{M}}, B))
end
_broadcast!(f, destsize, dest, argsizes, as...)
end


Expand Down Expand Up @@ -183,13 +134,6 @@ scalar_getindex(x::Tuple{<: Any}) = x[1]
end
end

if VERSION < v"0.7.0-DEV"
# Workaround for #329
@inline function Base.broadcast(f, ::Type{T}, a::StaticArray) where {T}
map(x->f(T,x), a)
end
end

####################################################
## Internal broadcast! machinery for StaticArrays ##
####################################################
Expand Down
32 changes: 13 additions & 19 deletions src/cholesky.jl
Original file line number Diff line number Diff line change
@@ -1,26 +1,19 @@
# Generic Cholesky decomposition for fixed-size matrices, mostly unrolled
if isdefined(Compat.LinearAlgebra, :non_hermitian_error)
non_hermitian_error() = Compat.LinearAlgebra.non_hermitian_error("chol")
else
non_hermitian_error() = throw(Compat.LinearAlgebra.PosDefException(-1))
end
@inline function LinearAlgebra.chol(A::StaticMatrix)
non_hermitian_error() = throw(LinearAlgebra.PosDefException(-1))
@inline function LinearAlgebra.cholesky(A::StaticMatrix)
ishermitian(A) || non_hermitian_error()
_chol(Size(A), A)
C = _cholesky(Size(A), A)
return Cholesky(C, 'U', 0)
end

@inline function LinearAlgebra.chol(A::LinearAlgebra.RealHermSymComplexHerm{<:Real, <:StaticMatrix})
_chol(Size(A), A.data)
end
if VERSION < v"0.7.0-DEV.393"
@inline LinearAlgebra._chol!(A::StaticMatrix, ::Type{UpperTriangular}) = chol(A)
else
# TODO should return non-zero info instead of throwing on errors
@inline LinearAlgebra._chol!(A::StaticMatrix, ::Type{UpperTriangular}) = (chol(A), 0)
@inline function LinearAlgebra.cholesky(A::LinearAlgebra.RealHermSymComplexHerm{<:Real, <:StaticMatrix})
C = _cholesky(Size(A), A.data)
return Cholesky(C, 'U', 0)
end
@inline LinearAlgebra._chol!(A::StaticMatrix, ::Type{UpperTriangular}) = (cholesky(A).U, 0)


@generated function _chol(::Size{(1,1)}, A::StaticMatrix)
@generated function _cholesky(::Size{(1,1)}, A::StaticMatrix)
@assert size(A) == (1,1)

quote
Expand All @@ -30,7 +23,7 @@ end
end
end

@generated function _chol(::Size{(2,2)}, A::StaticMatrix)
@generated function _cholesky(::Size{(2,2)}, A::StaticMatrix)
@assert size(A) == (2,2)

quote
Expand All @@ -43,7 +36,7 @@ end
end
end

@generated function _chol(::Size{(3,3)}, A::StaticMatrix)
@generated function _cholesky(::Size{(3,3)}, A::StaticMatrix)
@assert size(A) == (3,3)

quote
Expand All @@ -60,4 +53,5 @@ end
end

# Otherwise default algorithm returning wrapped SizedArray
@inline _chol(s::Size, A::StaticArray) = s(Matrix(chol(Hermitian(Array(A)))))
@inline _cholesky(s::Size, A::StaticArray) = s(Matrix(cholesky(Hermitian(Matrix(A))).U))
LinearAlgebra.hermitian_type(::Type{SA}) where {T, S, SA<:SArray{S,T}} = Hermitian{T,SA}
Loading

0 comments on commit 08053ba

Please sign in to comment.