Skip to content

Commit 20ee02a

Browse files
helgeemauro3
authored andcommitted
Support Julia 0.7, drop 0.6
1 parent e83f162 commit 20ee02a

File tree

6 files changed

+60
-65
lines changed

6 files changed

+60
-65
lines changed

.travis.yml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,7 @@ os:
44
- linux
55
- osx
66
julia:
7-
- 0.5
8-
- 0.6
7+
- 0.7
98
- nightly
109
matrix:
1110
allow_failures:

REQUIRE

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
julia 0.5
2-
StatsBase 0.15
3-
Reexport 0.0.3
1+
julia 0.7-beta
2+
StatsBase 0.24.0
3+
Reexport 0.1.0

appveyor.yml

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
environment:
22
matrix:
3-
- JULIA_URL: "https://julialang-s3.julialang.org/bin/winnt/x86/0.5/julia-0.5-latest-win32.exe"
4-
- JULIA_URL: "https://julialang-s3.julialang.org/bin/winnt/x64/0.5/julia-0.5-latest-win64.exe"
5-
- JULIA_URL: "https://julialang-s3.julialang.org/bin/winnt/x86/0.6/julia-0.6-latest-win32.exe"
6-
- JULIA_URL: "https://julialang-s3.julialang.org/bin/winnt/x64/0.6/julia-0.6-latest-win64.exe"
7-
#- JULIA_URL: "https://julialangnightlies-s3.julialang.org/bin/winnt/x86/julia-latest-win32.exe"
8-
#- JULIA_URL: "https://julialangnightlies-s3.julialang.org/bin/winnt/x64/julia-latest-win64.exe"
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"
7+
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"
912

1013
branches:
1114
only:

src/SmoothingSplines.jl

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ module SmoothingSplines
44

55
import StatsBase: fit!, fit, RegressionModel, rle, ordinalrank, mean
66
using Reexport
7+
using LinearAlgebra
78

89
export SmoothingSpline
910

@@ -13,7 +14,7 @@ LAPACKFloat = Union{Float32,Float64}
1314

1415
include("matrices.jl")
1516

16-
type SmoothingSpline{T<:LAPACKFloat} <: RegressionModel
17+
mutable struct SmoothingSpline{T<:LAPACKFloat} <: RegressionModel
1718
Xorig::Vector{T} # original grid points, but sorted
1819
Yorig::Vector{T} # original values, sorted according to x
1920
Xrank::Vector{Int}
@@ -27,26 +28,26 @@ type SmoothingSpline{T<:LAPACKFloat} <: RegressionModel
2728
λ::T
2829
end
2930

30-
function fit{T<:LAPACKFloat}(::Type{SmoothingSpline}, X::AbstractVector{T}, Y::AbstractVector{T}, λ::T, wts::AbstractVector{T}=ones(Y))
31+
function fit(::Type{SmoothingSpline}, X::AbstractVector{T}, Y::AbstractVector{T}, λ::T, wts::AbstractVector{T}=fill(1.0, length(Y))) where T <: LAPACKFloat
3132
Xrank = ordinalrank(X) # maybe speed this up when already sorted
3233
Xperm = sortperm(X)
3334
Xorig = X[Xperm]
3435
Yorig = Y[Xperm]
3536

3637
Xdesign, Xcount = rle(Xorig)
37-
ws = zeros(Xdesign)
38-
Ydesign = zeros(Xdesign)
38+
ws = zero(Xdesign)
39+
Ydesign = zero(Xdesign)
3940
running_rle_mean!(Ydesign, ws, Yorig, Xcount, wts[Xperm])
4041

4142
RpαQtQ = QtQpR(diff(Xdesign), λ, ws)
4243
pbtrf!('U', 2, RpαQtQ)
4344

4445
spl = SmoothingSpline{T}(Xorig, Yorig, Xrank, Xdesign, Xcount, Ydesign, ws, RpαQtQ,
45-
zeros(Xdesign), zeros(T,length(Xdesign)-2), λ)
46+
zero(Xdesign), fill(zero(T),length(Xdesign)-2), λ)
4647
fit!(spl)
4748
end
4849

49-
function fit!{T<:LAPACKFloat}(spl::SmoothingSpline{T})
50+
function fit!(spl::SmoothingSpline{T}) where T<:LAPACKFloat
5051
Y = spl.Ydesign
5152
ws = spl.weights
5253
g = spl.g
@@ -65,17 +66,17 @@ function fit!{T<:LAPACKFloat}(spl::SmoothingSpline{T})
6566
spl
6667
end
6768

68-
function fit!{T<:LAPACKFloat}(spl::SmoothingSpline{T}, Y::AbstractVector{T})
69+
function fit!(spl::SmoothingSpline{T}, Y::AbstractVector{T}) where T<:LAPACKFloat
6970
spl.Y = Y[spl.idx]
7071
fit!(spl)
7172
end
7273

7374

74-
function predict{T<:LAPACKFloat}(spl::SmoothingSpline{T})
75+
function predict(spl::SmoothingSpline{T}) where T<:LAPACKFloat
7576
# need to convert back from RLE encoding
7677
Xcount = spl.Xcount
7778
curridx = 1::Int
78-
g = zeros(length(spl.Yorig))
79+
g = fill(0.0, length(spl.Yorig))
7980
@inbounds for i=1:length(Xcount)
8081
@inbounds for j=1:Xcount[i]
8182
g[curridx] = spl.g[i]
@@ -85,7 +86,7 @@ function predict{T<:LAPACKFloat}(spl::SmoothingSpline{T})
8586
g[spl.Xrank]
8687
end
8788

88-
function predict{T<:SmoothingSplines.LAPACKFloat}(spl::SmoothingSpline{T}, x::T)
89+
function predict(spl::SmoothingSpline{T}, x::T) where T<:LAPACKFloat
8990
n = length(spl.Xdesign)
9091
idxl = searchsortedlast(spl.Xdesign, x)
9192
idxr = idxl + 1
@@ -119,8 +120,8 @@ function predict{T<:SmoothingSplines.LAPACKFloat}(spl::SmoothingSpline{T}, x::T)
119120
val
120121
end
121122

122-
function predict{T<:SmoothingSplines.LAPACKFloat}(spl::SmoothingSpline{T}, xs::AbstractVector{T})
123-
g = zeros(xs)
123+
function predict(spl::SmoothingSpline{T}, xs::AbstractVector{T}) where T<:SmoothingSplines.LAPACKFloat
124+
g = zero(xs)
124125
for (i,x) in enumerate(xs)
125126
# can be made more efficient as in StatsBase ECDF code
126127
g[i] = predict(spl, x)
@@ -129,7 +130,7 @@ function predict{T<:SmoothingSplines.LAPACKFloat}(spl::SmoothingSpline{T}, xs::A
129130
end
130131

131132
# update g and w in place
132-
function running_rle_mean!{T<:Real}(g::AbstractVector{T}, w::AbstractVector{T}, Y::AbstractVector{T}, rlecount::AbstractVector{Int}, ws::AbstractVector{T})
133+
function running_rle_mean!(g::AbstractVector{T}, w::AbstractVector{T}, Y::AbstractVector{T}, rlecount::AbstractVector{Int}, ws::AbstractVector{T}) where T<:Real
133134
length(g) == length(rlecount) || throw(DimensionMismatch())
134135
length(Y) == length(ws) || throw(DimensionMismatch())
135136
curridx = 1::Int

src/matrices.jl

Lines changed: 21 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
import Base.LinAlg.LAPACK: chkstride1, chkuplo, BlasInt, liblapack
1+
import LinearAlgebra.LAPACK: chkstride1, chkuplo, BlasInt, liblapack
2+
import LinearAlgebra.BLAS: @blasfunc
23

3-
4-
immutable ReinschQ{T} <: AbstractMatrix{T}
4+
struct ReinschQ{T} <: AbstractMatrix{T}
55
h::Vector{T}
66
end
77

@@ -10,7 +10,7 @@ function Base.size(Q::ReinschQ)
1010
(n+1, n-1)
1111
end
1212

13-
function Base.getindex{T}(Q::ReinschQ{T},i::Int,j::Int)
13+
function Base.getindex(Q::ReinschQ{T},i::Int,j::Int) where T
1414
h = Q.h
1515
if (i == j)
1616
1/h[i]
@@ -23,7 +23,7 @@ function Base.getindex{T}(Q::ReinschQ{T},i::Int,j::Int)
2323
end
2424
end
2525

26-
function Base.LinAlg.At_mul_B!(out::AbstractVector, Q::ReinschQ, g::AbstractVector)
26+
function LinearAlgebra.At_mul_B!(out::AbstractVector, Q::ReinschQ, g::AbstractVector)
2727
n = length(out)
2828
h = Q.h
2929
n == size(Q,2) || throw(DimensionMismatch())
@@ -37,7 +37,7 @@ function Base.LinAlg.At_mul_B!(out::AbstractVector, Q::ReinschQ, g::AbstractVect
3737
out
3838
end
3939

40-
function Base.LinAlg.A_mul_B!(out::AbstractVector, Q::ReinschQ, g::AbstractVector)
40+
function LinearAlgebra.A_mul_B!(out::AbstractVector, Q::ReinschQ, g::AbstractVector)
4141
n = length(out)
4242
n == size(Q,1) || throw(DimensionMismatch())
4343
length(g) == size(Q,2) || throw(DimensionMismatch())
@@ -51,7 +51,7 @@ function Base.LinAlg.A_mul_B!(out::AbstractVector, Q::ReinschQ, g::AbstractVecto
5151
end
5252

5353

54-
immutable ReinschR{T} <: AbstractMatrix{T}
54+
struct ReinschR{T} <: AbstractMatrix{T}
5555
h::Vector{T}
5656
end
5757

@@ -60,7 +60,7 @@ function Base.size(R::ReinschR)
6060
(n-1, n-1)
6161
end
6262

63-
function Base.getindex{T}(R::ReinschR{T}, i::Int, j::Int)
63+
function Base.getindex(R::ReinschR{T}, i::Int, j::Int) where T
6464
# TODO: add check bounds
6565
h = R.h
6666
if (i==j)
@@ -72,7 +72,7 @@ function Base.getindex{T}(R::ReinschR{T}, i::Int, j::Int)
7272
end
7373
end
7474

75-
function QtQpR{T<:Real}(h::AbstractVector{T}, α::T, w::AbstractVector{T}=ones(T, length(h)+1))
75+
function QtQpR(h::AbstractVector{T}, α::T, w::AbstractVector{T}=ones(T, length(h)+1)) where T<:Real
7676
# maybe has some redundant calculations but should be good enough for now
7777
n = length(h)-1
7878
Q = ReinschQ(h)
@@ -97,23 +97,12 @@ function QtQpR{T<:Real}(h::AbstractVector{T}, α::T, w::AbstractVector{T}=ones(T
9797
out
9898
end
9999

100-
# temporary hack to use LAPACK wrapper,
101-
# as in
102-
# https://github.com/ApproxFun/BandedMatrices.jl/blob/master/src/blas.jl
103-
if VERSION < v"0.5.0-dev"
104-
macro blasfunc(x)
105-
return :( $(BLAS.blasfunc(x) ))
106-
end
107-
else
108-
import Base.BLAS.@blasfunc
109-
end
110-
111100

112101
for (pbtrf, pbtrs, elty) in
113102
((:dpbtrf_,:dpbtrs_,:Float64),
114103
(:spbtrf_,:spbtrs_,:Float32),
115-
(:zpbtrf_,:zpbtrs_,:Complex128),
116-
(:cpbtrf_,:cpbtrs_,:Complex64))
104+
(:zpbtrf_,:zpbtrs_,:ComplexF64),
105+
(:cpbtrf_,:cpbtrs_,:ComplexF32))
117106
@eval begin
118107
# SUBROUTINE DPBTRF( UPLO, N, KD, AB, LDAB, INFO )
119108
# * .. Scalar Arguments ..
@@ -127,10 +116,10 @@ for (pbtrf, pbtrs, elty) in
127116
chkstride1(AB)
128117
n = size(AB, 2)
129118
info = Ref{BlasInt}()
130-
ccall((@blasfunc($pbtrf), liblapack), Void,
131-
(Ptr{UInt8}, Ptr{BlasInt}, Ptr{BlasInt},
132-
Ptr{$elty}, Ptr{BlasInt}, Ptr{BlasInt}),
133-
&uplo, &n, &kd, AB, &max(1,stride(AB,2)), info)
119+
ccall((@blasfunc($pbtrf), liblapack), Cvoid,
120+
(Ref{UInt8}, Ref{BlasInt}, Ref{BlasInt},
121+
Ptr{$elty}, Ref{BlasInt}, Ref{BlasInt}),
122+
uplo, n, kd, AB, max(1,stride(AB,2)), info)
134123
AB
135124
end
136125

@@ -150,12 +139,12 @@ for (pbtrf, pbtrs, elty) in
150139
if n != size(B,1)
151140
throw(DimensionMismatch("Matrix AB has dimensions $(size(AB)), but right hand side matrix B has dimensions $(size(B))"))
152141
end
153-
ccall((@blasfunc($pbtrs), liblapack), Void,
154-
(Ptr{UInt8}, Ptr{BlasInt}, Ptr{BlasInt}, Ptr{BlasInt},
155-
Ptr{$elty}, Ptr{BlasInt}, Ptr{$elty}, Ptr{BlasInt},
156-
Ptr{BlasInt}),
157-
&uplo, &n, &kd, &size(B,2), AB, &max(1,stride(AB,2)),
158-
B, &max(1,stride(B,2)), info)
142+
ccall((@blasfunc($pbtrs), liblapack), Cvoid,
143+
(Ref{UInt8}, Ref{BlasInt}, Ref{BlasInt}, Ref{BlasInt},
144+
Ptr{$elty}, Ref{BlasInt}, Ptr{$elty}, Ref{BlasInt},
145+
Ref{BlasInt}),
146+
uplo, n, kd, size(B,2), AB, max(1,stride(AB,2)),
147+
B, max(1,stride(B,2)), info)
159148
B
160149
end
161150
end

test/runtests.jl

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
using SmoothingSplines
2-
using Base.Test
2+
using Test
3+
4+
using LinearAlgebra
5+
using Random
36

47
#n=50
58
#X = rand(n) .* 3
@@ -17,7 +20,7 @@ X = [0.0; cumsum(h)]
1720
λ = 1.0
1821

1922
ws1 = ones(Float64, length(Y))
20-
ws2 = 1.0 + rand(n)
23+
ws2 = 1.0 .+ rand(n)
2124
ws_dict = Dict("uniform weights"=> ws1, "random weights"=>ws2)
2225
for (k,ws) in ws_dict
2326
println(k)
@@ -26,12 +29,12 @@ for (k,ws) in ws_dict
2629
Qfull = reshape(Float64[x for x in Q], size(Q))
2730
Rfull = reshape(Float64[x for x in R], size(R))
2831
QtYfull = Qfull'*Y
29-
QtY = At_mul_B!(zeros(n-2), Q, Y)
32+
QtY = At_mul_B!(fill(0.0, n-2), Q, Y)
3033

3134
@test QtY QtYfull
3235

3336

34-
tmpQtQpRfull = Rfull + λ*Qfull'*diagm(1./ws)*Qfull
37+
tmpQtQpRfull = Rfull + λ*Qfull'*Matrix(Diagonal(1.0 ./ ws))*Qfull
3538
tmpQtQpR =SmoothingSplines. QtQpR(h, λ, ws)
3639
@test vec(tmpQtQpR[3,:]) diag(tmpQtQpRfull)
3740
@test vec(tmpQtQpR[2,2:end]) diag(tmpQtQpRfull,1)
@@ -43,8 +46,8 @@ for (k,ws) in ws_dict
4346
SmoothingSplines.pbtrs!('U', 2, tmpQtQpR, γ)
4447
@test γ γfull
4548

46-
gfull = Y - λ*diagm(1./ws)*Qfull*γfull
47-
g = Y - λ*A_mul_B!(zeros(Y), Q, γ)./ws
49+
gfull = Y - λ*Matrix(Diagonal(1.0./ws))*Qfull*γfull
50+
g = Y - λ*A_mul_B!(zero(Y), Q, γ)./ws
4851
@test g gfull
4952

5053
fullfit = fit(SmoothingSpline, X, Y, λ, ws)
@@ -54,7 +57,7 @@ println("testing predict function")
5457
srand(1)
5558
n=50
5659
X = rand(n) .* 3
57-
Y = 2 .* X.^2 - X .- randn(n)
60+
Y = 2 .* X.^2 .- X .- randn(n)
5861

5962
spl = fit(SmoothingSpline, X, Y, 1.0)
6063

@@ -76,7 +79,7 @@ Y = [2.0,10.0,4.0,22.0,16.0,10.0,18.0,26.0,34.0,17.0,28.0,14.0,20.0,24.0,
7679
32.0,40.0,50.0,42.0,56.0,76.0,84.0,36.0,46.0,68.0,32.0,48.0,52.0,56.0,
7780
64.0,66.0,54.0,70.0,92.0,93.0,120.0,85.0]
7881
# so that λ for this package is comparable to λ in smooth.spline
79-
X = (X-minimum(X))/(maximum(X)-minimum(X))
82+
X = (X .- minimum(X))/(maximum(X)-minimum(X))
8083

8184
# compare to R.stats:
8285
# attach(cars)
@@ -87,4 +90,4 @@ Rpred = [ 1.657809, 11.682913, 15.064409, 18.482339, 21.947078, 25.465623, 29.0
8790
32.707552, 36.423468, 40.195168, 44.054188, 48.025219, 52.115627, 56.323874,
8891
60.673887, 69.808295, 74.533703, 79.313597, 84.103688]
8992
cars_fit = fit(SmoothingSpline, X, Y, λ)
90-
@test_approx_eq_eps cars_fit.g Rpred 1e-4
93+
@test cars_fit.g Rpred rtol=1e-4

0 commit comments

Comments
 (0)