Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fixes for 0.7 #451

Merged
merged 6 commits into from
Jun 29, 2018
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,17 @@ os:
- linux
- osx
julia:
- 0.6
- 0.7
- nightly
notifications:
email: false
branches:
only:
- master
- /^v[0-9]+\.[0-9]+\.[0-9]+$/ # version tags for Documenter.jl, see # 298
matrix:
allow_failures:
- julia: nightly
# matrix:
# allow_failures:
# - julia: nightly
# - os: osx
# uncomment the following lines to override the default test script
#script:
Expand Down
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
12 changes: 6 additions & 6 deletions appveyor.yml
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
environment:
matrix:
- JULIA_URL: "https://julialang-s3.julialang.org/bin/winnt/x86/0.6/julia-0.6-latest-win32.exe"
- JULIA_URL: "https://julialang-s3.julialang.org/bin/winnt/x64/0.6/julia-0.6-latest-win64.exe"
- JULIA_URL: "https://julialang-s3.julialang.org/bin/winnt/x86/0.7/julia-0.7-latest-win32.exe"
- JULIA_URL: "https://julialang-s3.julialang.org/bin/winnt/x64/0.7/julia-0.7-latest-win64.exe"
- JULIA_URL: "https://julialangnightlies-s3.julialang.org/bin/winnt/x86/julia-latest-win32.exe"
- JULIA_URL: "https://julialangnightlies-s3.julialang.org/bin/winnt/x64/julia-latest-win64.exe"

matrix:
allow_failures:
- JULIA_URL: "https://julialangnightlies-s3.julialang.org/bin/winnt/x86/julia-latest-win32.exe"
- JULIA_URL: "https://julialangnightlies-s3.julialang.org/bin/winnt/x64/julia-latest-win64.exe"
# matrix:
# allow_failures:
# - JULIA_URL: "https://julialangnightlies-s3.julialang.org/bin/winnt/x86/julia-latest-win32.exe"
# - JULIA_URL: "https://julialangnightlies-s3.julialang.org/bin/winnt/x64/julia-latest-win64.exe"

branches:
only:
Expand Down
22 changes: 22 additions & 0 deletions docs/src/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,25 @@ Mutable versions [`MVector`](@ref), [`MMatrix`](@ref) and [`MArray`](@ref) are a
as [`SizedArray`](@ref) for annotating standard `Array`s with static size information.
Further, the abstract [`FieldVector`](@ref) can be used to make fast static vectors
out of any uniform Julia "struct".

## Migrating code from Julia v0.6 to Julia v0.7

When upgrading code that is depending on **StaticArrays** the following notes may be helpful

* `chol` has been renamed to `cholesky` and return a factorization object. To obtain the factor
use `C = cholesky(A).U`, just like for regular Julia arrays.

* `lu` now return a factorization object instead of a tuple with `L`, `U`, and `p`.
They can be obtained by destructing via iteration (`L, U, p = lu(A)`) or by
using `getfield` (`F = lu(A); L, U, p = F.L, F.U, F.p`).

* `qr` now return a factorization object instead of a tuple with `Q` and `R`.
They can be obtained by destructing via iteration (`Q, R = qr(A)`) or by
using `getfield` (`F = qr(A); Q, R = F.Q, F.R`)

* `eig` has been renamed to `eigen`, which return a factorization object, rather than
a tuple with `(values, vectors)`. They can be obtained by destructing via iteration
(`values, vectors = eigen(A)`) or by using `getfield`
(`E = eigen(A); values, vectors = E.values, E.vectors`).

* `unshift` and `shift` have been renamed to `pushfirst` and `popfirst`.
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
47 changes: 10 additions & 37 deletions src/StaticArrays.jl
Original file line number Diff line number Diff line change
Expand Up @@ -10,42 +10,15 @@ 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

export StaticScalar, StaticArray, StaticVector, StaticMatrix
export Scalar, SArray, SVector, SMatrix
Expand All @@ -60,7 +33,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
Loading