Skip to content

Commit 1bc691d

Browse files
authored
Merge pull request #473 from simonbyrne/sb/1.0
Working on 1.0
2 parents 8aab1dd + df586c1 commit 1bc691d

File tree

8 files changed

+136
-154
lines changed

8 files changed

+136
-154
lines changed

appveyor.yml

+18-21
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,23 @@
11
environment:
22
matrix:
3-
- JULIA_URL: "https://julialang-s3.julialang.org/bin/winnt/x86/0.7/julia-0.7-latest-win32.exe"
4-
- JULIA_URL: "https://julialang-s3.julialang.org/bin/winnt/x64/0.7/julia-0.7-latest-win64.exe"
5-
- JULIA_URL: "https://julialangnightlies-s3.julialang.org/bin/winnt/x86/julia-latest-win32.exe"
6-
- JULIA_URL: "https://julialangnightlies-s3.julialang.org/bin/winnt/x64/julia-latest-win64.exe"
3+
- julia_version: 0.7
4+
- julia_version: 1.0
5+
- julia_version: latest
76

8-
# matrix:
9-
# allow_failures:
10-
# - JULIA_URL: "https://julialangnightlies-s3.julialang.org/bin/winnt/x86/julia-latest-win32.exe"
11-
# - JULIA_URL: "https://julialangnightlies-s3.julialang.org/bin/winnt/x64/julia-latest-win64.exe"
7+
platform:
8+
- x86 # 32-bit
9+
- x64 # 64-bit
10+
11+
## uncomment the following lines to allow failures on nightly julia
12+
## (tests will run but not make your overall status red)
13+
#matrix:
14+
# allow_failures:
15+
# - julia_version: latest
1216

1317
branches:
1418
only:
1519
- master
16-
# - /release-.*/
20+
- /release-.*/
1721

1822
notifications:
1923
- provider: Email
@@ -22,19 +26,12 @@ notifications:
2226
on_build_status_changed: false
2327

2428
install:
25-
- ps: "[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12"
26-
# Download most recent Julia Windows binary
27-
- ps: (new-object net.webclient).DownloadFile(
28-
$env:JULIA_URL,
29-
"C:\projects\julia-binary.exe")
30-
# Run installer silently, output to C:\projects\julia
31-
- C:\projects\julia-binary.exe /S /D=C:\projects\julia
29+
- ps: iex ((new-object net.webclient).DownloadString("https://raw.githubusercontent.com/JuliaCI/Appveyor.jl/version-1/bin/install.ps1"))
3230

3331
build_script:
34-
# Need to convert from shallow to complete for Pkg.clone to work
35-
- IF EXIST .git\shallow (git fetch --unshallow)
36-
- C:\projects\julia\bin\julia -e "versioninfo();
37-
Pkg.clone(pwd(), \"StaticArrays\"); Pkg.build(\"StaticArrays\")"
32+
- echo "%JL_BUILD_SCRIPT%"
33+
- C:\julia\bin\julia -e "%JL_BUILD_SCRIPT%"
3834

3935
test_script:
40-
- C:\projects\julia\bin\julia --check-bounds=yes -e "Pkg.test(\"StaticArrays\")"
36+
- echo "%JL_TEST_SCRIPT%"
37+
- C:\julia\bin\julia -e "%JL_TEST_SCRIPT%"

src/FixedSizeArrays.jl

+3-3
Original file line numberDiff line numberDiff line change
@@ -75,13 +75,13 @@ export unit
7575

7676
function Base.extrema(a::AbstractVector{T}) where T <: StaticVector
7777
ET = eltype(T)
78-
reduce((x, v)-> (min.(x[1], v), max.(x[2], v)), (T(typemax(ET)), T(typemin(ET))), a)
78+
reduce((x, v)-> (min.(x[1], v), max.(x[2], v)), a; init = (T(typemax(ET)), T(typemin(ET))))
7979
end
8080
function Base.minimum(a::AbstractVector{T}) where T <: StaticVector
81-
reduce((x, v)-> min.(x[1], v), T(typemax(eltype(T))), a)
81+
reduce((x, v)-> min.(x[1], v), a; init=T(typemax(eltype(T))))
8282
end
8383
function Base.maximum(a::AbstractVector{T}) where T <: StaticVector
84-
reduce((x, v)-> max.(x[1], v), T(typemin(eltype(T))), a)
84+
reduce((x, v)-> max.(x[1], v), a; init=T(typemin(eltype(T))))
8585
end
8686

8787

src/StaticArrays.jl

+5-8
Original file line numberDiff line numberDiff line change
@@ -3,26 +3,23 @@ module StaticArrays
33
import Base: @_inline_meta, @_propagate_inbounds_meta, @_pure_meta, @propagate_inbounds, @pure
44

55
import Base: getindex, setindex!, size, similar, vec, show, length, convert, promote_op,
6-
promote_rule, map, map!, reduce, reducedim, mapreducedim, mapreduce, broadcast,
6+
promote_rule, map, map!, reduce, mapreduce, broadcast,
77
broadcast!, conj, hcat, vcat, ones, zeros, one, reshape, fill, fill!, inv,
88
iszero, sum, prod, count, any, all, minimum, maximum, extrema,
99
copy, read, read!, write
1010

11-
if VERSION >= v"0.7.0-beta.85"
12-
import Statistics: mean
13-
else
14-
import Base: mean
15-
end
11+
import Statistics: mean
1612

1713
using Random
1814
import Random: rand, randn, randexp, rand!, randn!, randexp!
1915
using Core.Compiler: return_type
2016
import Base: sqrt, exp, log
2117
using LinearAlgebra
22-
import LinearAlgebra: transpose, adjoint, vecdot, eigvals, eigen, lyap, tr,
23-
kron, diag, norm, dot, diagm, lu, svd, svdvals, svdfact,
18+
import LinearAlgebra: transpose, adjoint, dot, eigvals, eigen, lyap, tr,
19+
kron, diag, norm, dot, diagm, lu, svd, svdvals,
2420
factorize, ishermitian, issymmetric, isposdef, normalize,
2521
normalize!, Eigen, det, logdet, cross, diff, qr
22+
2623
# import eye for deprecation warnings
2724
@static if isdefined(LinearAlgebra, :eye)
2825
import LinearAlgebra: eye

src/expm.jl

+1-1
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ function _exp(::Size, _A::StaticMatrix{<:Any,<:Any,T}) where T
6868
S = typeof((zero(T)*zero(T) + zero(T)*zero(T))/one(T))
6969
A = S.(_A)
7070
# omitted: matrix balancing, i.e., LAPACK.gebal!
71-
nA = maximum(sum(abs.(A), Val{1})) # marginally more performant than norm(A, 1)
71+
nA = maximum(sum(abs.(A); dims=Val(1))) # marginally more performant than norm(A, 1)
7272
## For sufficiently small nA, use lower order Padé-Approximations
7373
if (nA <= 2.1)
7474
A2 = A*A

src/linalg.jl

+3-4
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,6 @@ end
223223
end
224224

225225
@inline dot(a::StaticVector, b::StaticVector) = _vecdot(same_size(a, b), a, b)
226-
@inline vecdot(a::StaticArray, b::StaticArray) = _vecdot(same_size(a, b), a, b)
227226
@generated function _vecdot(::Size{S}, a::StaticArray, b::StaticArray) where {S}
228227
if prod(S) == 0
229228
return :(zero(promote_op(*, eltype(a), eltype(b))))
@@ -257,7 +256,7 @@ end
257256
end
258257
end
259258

260-
@inline LinearAlgebra.norm_sqr(v::StaticVector) = mapreduce(abs2, +, zero(real(eltype(v))), v)
259+
@inline LinearAlgebra.norm_sqr(v::StaticVector) = mapreduce(abs2, +, v; init=zero(real(eltype(v))))
261260

262261
@inline norm(a::StaticArray) = _norm(Size(a), a)
263262
@generated function _norm(::Size{S}, a::StaticArray) where {S}
@@ -297,13 +296,13 @@ _norm_p0(x) = x == 0 ? zero(x) : one(x)
297296
return quote
298297
$(Expr(:meta, :inline))
299298
if p == Inf
300-
return mapreduce(abs, max, $(zero(real(eltype(a)))), a)
299+
return mapreduce(abs, max, a; init=$(zero(real(eltype(a)))))
301300
elseif p == 1
302301
@inbounds return $expr_p1
303302
elseif p == 2
304303
return norm(a)
305304
elseif p == 0
306-
return mapreduce(_norm_p0, +, $(zero(real(eltype(a)))), a)
305+
return mapreduce(_norm_p0, +, a; init=$(zero(real(eltype(a)))))
307306
else
308307
@inbounds return ($expr)^(inv(p))
309308
end

src/mapreduce.jl

+68-87
Original file line numberDiff line numberDiff line change
@@ -60,15 +60,12 @@ end
6060
## mapreduce ##
6161
###############
6262

63-
@inline function mapreduce(f, op, a::StaticArray, b::StaticArray...)
64-
_mapreduce(f, op, same_size(a, b...), a, b...)
63+
@inline function mapreduce(f, op, a::StaticArray, b::StaticArray...; dims=:,kw...)
64+
_mapreduce(f, op, dims, kw.data, same_size(a, b...), a, b...)
6565
end
6666

67-
@inline function mapreduce(f, op, v0, a::StaticArray, b::StaticArray...)
68-
_mapreduce(f, op, v0, same_size(a, b...), a, b...)
69-
end
70-
71-
@generated function _mapreduce(f, op, ::Size{S}, a::StaticArray...) where {S}
67+
@generated function _mapreduce(f, op, dims::Colon, nt::NamedTuple{()},
68+
::Size{S}, a::StaticArray...) where {S}
7269
tmp = [:(a[$j][1]) for j 1:length(a)]
7370
expr = :(f($(tmp...)))
7471
for i 2:prod(S)
@@ -80,9 +77,10 @@ end
8077
@inbounds return $expr
8178
end
8279
end
83-
84-
@generated function _mapreduce(f, op, v0, ::Size{S}, a::StaticArray...) where {S}
85-
expr = :v0
80+
81+
@generated function _mapreduce(f, op, dims::Colon, nt::NamedTuple{(:init,)},
82+
::Size{S}, a::StaticArray...) where {S}
83+
expr = :(nt.init)
8684
for i 1:prod(S)
8785
tmp = [:(a[$j][$i]) for j 1:length(a)]
8886
expr = :(op($expr, f($(tmp...))))
@@ -93,22 +91,16 @@ end
9391
end
9492
end
9593

96-
##################
97-
## mapreducedim ##
98-
##################
99-
100-
# I'm not sure why the signature for this from Base precludes multiple arrays?
101-
# (also, why not mutating `mapreducedim!` and `reducedim!`?)
102-
# (similarly, `broadcastreduce` and `broadcastreducedim` sounds useful)
103-
@inline function mapreducedim(f, op, a::StaticArray, ::Type{Val{D}}) where {D}
104-
_mapreducedim(f, op, Size(a), a, Val{D})
105-
end
106-
107-
@inline function mapreducedim(f, op, a::StaticArray, ::Type{Val{D}}, v0) where {D}
108-
_mapreducedim(f, op, Size(a), a, Val{D}, v0)
94+
@inline function _mapreduce(f, op, ::Type{Val{D}}, nt::NamedTuple,sz::Size{S}, a::StaticArray) where {S,D}
95+
Base.depwarn("`Val{D}` as dims argument is deprecated, use `D` or `Val(D)` instead.")
96+
_mapreduce(f, op, Val(D), nt, sz, a)
10997
end
98+
@inline _mapreduce(f, op, D::Int, nt::NamedTuple, sz::Size{S}, a::StaticArray) where {S} =
99+
_mapreduce(f, op, Val(D), nt, sz, a)
110100

111-
@generated function _mapreducedim(f, op, ::Size{S}, a::StaticArray, ::Type{Val{D}}) where {S,D}
101+
102+
@generated function _mapreduce(f, op, dims::Val{D}, nt::NamedTuple{()},
103+
::Size{S}, a::StaticArray) where {S,D}
112104
N = length(S)
113105
Snew = ([n==D ? 1 : S[n] for n = 1:N]...,)
114106
T0 = eltype(a)
@@ -133,14 +125,15 @@ end
133125
end
134126
end
135127

136-
@generated function _mapreducedim(f, op, ::Size{S}, a::StaticArray, ::Type{Val{D}}, v0::T) where {S,D,T}
128+
@generated function _mapreduce(f, op, dims::Val{D}, nt::NamedTuple{(:init,),Tuple{T}},
129+
::Size{S}, a::StaticArray) where {S,D,T}
137130
N = length(S)
138131
Snew = ([n==D ? 1 : S[n] for n = 1:N]...,)
139132

140133
exprs = Array{Expr}(undef, Snew)
141134
itr = [1:n for n = Snew]
142135
for i Base.product(itr...)
143-
expr = :v0
136+
expr = :(nt.init)
144137
for k = 1:S[D]
145138
ik = collect(i)
146139
ik[D] = k
@@ -160,15 +153,7 @@ end
160153
## reduce ##
161154
############
162155

163-
@inline reduce(op, a::StaticArray) = mapreduce(identity, op, a)
164-
@inline reduce(op, v0, a::StaticArray) = mapreduce(identity, op, v0, a)
165-
166-
###############
167-
## reducedim ##
168-
###############
169-
170-
@inline reducedim(op, a::StaticArray, ::Type{Val{D}}) where {D} = mapreducedim(identity, op, a, Val{D})
171-
@inline reducedim(op, a::StaticArray, ::Type{Val{D}}, v0) where {D} = mapreducedim(identity, op, a, Val{D}, v0)
156+
@inline reduce(op, a::StaticArray; kw...) = mapreduce(identity, op, a; kw...)
172157

173158
#######################
174159
## related functions ##
@@ -178,68 +163,64 @@ end
178163
#
179164
# Implementation notes:
180165
#
181-
# 1. When providing an initial value v0, note that its location is different in reduce and
182-
# reducedim: v0 comes earlier than collection in reduce, whereas it is the last argument in
183-
# reducedim. The same difference exists between mapreduce and mapreducedim.
184-
#
185-
# 2. mapreduce and mapreducedim usually do not take initial value v0, because we don't
166+
# 1. mapreduce and mapreducedim usually do not take initial value, because we don't
186167
# always know the return type of an arbitrary mapping function f. (We usually want to use
187-
# some initial value such as one(T) or zero(T) as v0, where T is the return type of f, but
168+
# some initial value such as one(T) or zero(T), where T is the return type of f, but
188169
# if users provide type-unstable f, its return type cannot be known.) Therefore, mapped
189170
# versions of the functions implemented below usually require the collection to have at
190171
# least two entries.
191172
#
192-
# 3. Exceptions are the ones that require Boolean mapping functions. For example, f in
193-
# all and any must return Bool, so we know the appropriate v0 is true and false,
173+
# 2. Exceptions are the ones that require Boolean mapping functions. For example, f in
174+
# all and any must return Bool, so we know the appropriate initial value is true and false,
194175
# respectively. Therefore, all(f, ...) and any(f, ...) are implemented by mapreduce(f, ...)
195176
# with an initial value v0 = true and false.
196-
@inline iszero(a::StaticArray{<:Any,T}) where {T} = reduce((x,y) -> x && (y==zero(T)), true, a)
197-
198-
@inline sum(a::StaticArray{<:Any,T}) where {T} = reduce(+, zero(T), a)
199-
@inline sum(f::Function, a::StaticArray) = mapreduce(f, +, a)
200-
@inline sum(a::StaticArray{<:Any,T}, ::Type{Val{D}}) where {T,D} = reducedim(+, a, Val{D}, zero(T))
201-
@inline sum(f::Function, a::StaticArray, ::Type{Val{D}}) where D = mapreducedim(f, +, a, Val{D})
202-
203-
@inline prod(a::StaticArray{<:Any,T}) where {T} = reduce(*, one(T), a)
204-
@inline prod(f::Function, a::StaticArray{<:Any,T}) where {T} = mapreduce(f, *, a)
205-
@inline prod(a::StaticArray{<:Any,T}, ::Type{Val{D}}) where {T,D} = reducedim(*, a, Val{D}, one(T))
206-
@inline prod(f::Function, a::StaticArray{<:Any,T}, ::Type{Val{D}}) where {T,D} = mapreducedim(f, *, a, Val{D})
207-
208-
@inline count(a::StaticArray{<:Any,Bool}) = reduce(+, 0, a)
209-
@inline count(f::Function, a::StaticArray) = mapreduce(x->f(x)::Bool, +, 0, a)
210-
@inline count(a::StaticArray{<:Any,Bool}, ::Type{Val{D}}) where {D} = reducedim(+, a, Val{D}, 0)
211-
@inline count(f::Function, a::StaticArray, ::Type{Val{D}}) where {D} = mapreducedim(x->f(x)::Bool, +, a, Val{D}, 0)
212-
213-
@inline all(a::StaticArray{<:Any,Bool}) = reduce(&, true, a) # non-branching versions
214-
@inline all(f::Function, a::StaticArray) = mapreduce(x->f(x)::Bool, &, true, a)
215-
@inline all(a::StaticArray{<:Any,Bool}, ::Type{Val{D}}) where {D} = reducedim(&, a, Val{D}, true)
216-
@inline all(f::Function, a::StaticArray, ::Type{Val{D}}) where {D} = mapreducedim(x->f(x)::Bool, &, a, Val{D}, true)
217-
218-
@inline any(a::StaticArray{<:Any,Bool}) = reduce(|, false, a) # (benchmarking needed)
219-
@inline any(f::Function, a::StaticArray) = mapreduce(x->f(x)::Bool, |, false, a) # (benchmarking needed)
220-
@inline any(a::StaticArray{<:Any,Bool}, ::Type{Val{D}}) where {D} = reducedim(|, a, Val{D}, false)
221-
@inline any(f::Function, a::StaticArray, ::Type{Val{D}}) where {D} = mapreducedim(x->f(x)::Bool, |, a, Val{D}, false)
222-
223-
@inline mean(a::StaticArray) = sum(a) / length(a)
224-
@inline mean(f::Function, a::StaticArray) = sum(f, a) / length(a)
225-
@inline mean(a::StaticArray, ::Type{Val{D}}) where {D} = sum(a, Val{D}) / size(a, D)
226-
@inline mean(f::Function, a::StaticArray, ::Type{Val{D}}) where {D} = sum(f, a, Val{D}) / size(a, D)
227-
228-
@inline minimum(a::StaticArray) = reduce(min, a) # base has mapreduce(idenity, scalarmin, a)
229-
@inline minimum(f::Function, a::StaticArray) = mapreduce(f, min, a)
230-
@inline minimum(a::StaticArray, ::Type{Val{D}}) where {D} = reducedim(min, a, Val{D})
231-
@inline minimum(f::Function, a::StaticArray, ::Type{Val{D}}) where {D} = mapreducedim(f, min, a, Val{D})
232-
233-
@inline maximum(a::StaticArray) = reduce(max, a) # base has mapreduce(idenity, scalarmax, a)
234-
@inline maximum(f::Function, a::StaticArray) = mapreduce(f, max, a)
235-
@inline maximum(a::StaticArray, ::Type{Val{D}}) where {D} = reducedim(max, a, Val{D})
236-
@inline maximum(f::Function, a::StaticArray, ::Type{Val{D}}) where {D} = mapreducedim(f, max, a, Val{D})
177+
#
178+
# TODO: change to use Base.reduce_empty/Base.reduce_first
179+
@inline iszero(a::StaticArray{<:Any,T}) where {T} = reduce((x,y) -> x && iszero(y), a, init=true)
180+
181+
@inline sum(a::StaticArray{<:Any,T}; dims=:) where {T} = reduce(+, a; dims=dims)
182+
@inline sum(f, a::StaticArray{<:Any,T}; dims=:) where {T} = mapreduce(f, +, a; dims=dims)
183+
@inline sum(f::Union{Function, Type}, a::StaticArray{<:Any,T}; dims=:) where {T} = mapreduce(f, +, a; dims=dims) # avoid ambiguity
184+
185+
@inline prod(a::StaticArray{<:Any,T}; dims=:) where {T} = reduce(*, a; dims=dims)
186+
@inline prod(f, a::StaticArray{<:Any,T}; dims=:) where {T} = mapreduce(f, *, a; dims=dims)
187+
@inline prod(f::Union{Function, Type}, a::StaticArray{<:Any,T}; dims=:) where {T} = mapreduce(f, *, a; dims=dims)
188+
189+
@inline count(a::StaticArray{<:Any,Bool}; dims=:) = reduce(+, a; dims=dims)
190+
@inline count(f, a::StaticArray; dims=:) = mapreduce(x->f(x)::Bool, +, a; dims=dims)
191+
192+
@inline all(a::StaticArray{<:Any,Bool}; dims=:) = reduce(&, a; dims=dims, init=true) # non-branching versions
193+
@inline all(f::Function, a::StaticArray; dims=:) = mapreduce(x->f(x)::Bool, &, a; dims=dims, init=true)
194+
195+
@inline any(a::StaticArray{<:Any,Bool}; dims=:) = reduce(|, a; dims=dims, init=false) # (benchmarking needed)
196+
@inline any(f::Function, a::StaticArray; dims=:) = mapreduce(x->f(x)::Bool, |, a; dims=dims, init=false) # (benchmarking needed)
197+
198+
_mean_denom(a, dims::Colon) = length(a)
199+
_mean_denom(a, dims::Int) = size(a, dims)
200+
_mean_denom(a, ::Val{D}) where {D} = size(a, D)
201+
_mean_denom(a, ::Type{Val{D}}) where {D} = size(a, D)
202+
203+
@inline mean(a::StaticArray; dims=:) = sum(a; dims=dims) / _mean_denom(a,dims)
204+
@inline mean(f::Function, a::StaticArray;dims=:) = sum(f, a; dims=dims) / _mean_denom(a,dims)
205+
206+
@inline minimum(a::StaticArray; dims=:) = reduce(min, a; dims=dims) # base has mapreduce(idenity, scalarmin, a)
207+
@inline minimum(f::Function, a::StaticArray; dims=:) = mapreduce(f, min, a; dims=dims)
208+
209+
@inline maximum(a::StaticArray; dims=:) = reduce(max, a; dims=dims) # base has mapreduce(idenity, scalarmax, a)
210+
@inline maximum(f::Function, a::StaticArray; dims=:) = mapreduce(f, max, a; dims=dims)
237211

238212
# Diff is slightly different
239-
@inline diff(a::StaticArray) = diff(a, Val{1})
240-
@inline diff(a::StaticArray, ::Type{Val{D}}) where {D} = _diff(Size(a), a, Val{D})
213+
@inline diff(a::StaticArray; dims) = _diff(Size(a), a, dims)
214+
@inline diff(a::StaticVector) = diff(a;dims=Val(1))
241215

242-
@generated function _diff(::Size{S}, a::StaticArray, ::Type{Val{D}}) where {S,D}
216+
@inline function _diff(sz::Size{S}, a::StaticArray, D::Int) where {S}
217+
_diff(sz,a,Val(D))
218+
end
219+
@inline function _diff(sz::Size{S}, a::StaticArray, ::Type{Val{D}}) where {S,D}
220+
Base.depwarn("`Val{D}` as dims argument is deprecated, use `D` or `Val(D)` instead.")
221+
_diff(sz,a,Val(D))
222+
end
223+
@generated function _diff(::Size{S}, a::StaticArray, ::Val{D}) where {S,D}
243224
N = length(S)
244225
Snew = ([n==D ? S[n]-1 : S[n] for n = 1:N]...,)
245226

test/linalg.jl

+1-1
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ using StaticArrays, Test, LinearAlgebra
217217
end
218218

219219
@testset "size zero" begin
220-
@test vecdot(SVector{0, Float64}(()), SVector{0, Float64}(())) === 0.
220+
@test dot(SVector{0, Float64}(()), SVector{0, Float64}(())) === 0.
221221
@test StaticArrays.bilinear_vecdot(SVector{0, Float64}(()), SVector{0, Float64}(())) === 0.
222222
@test norm(SVector{0, Float64}(())) === 0.
223223
@test norm(SVector{0, Float64}(()), 1) === 0.

0 commit comments

Comments
 (0)