@@ -6,7 +6,8 @@ export iterateCSteps
66import .. Basis: RegressionSetting, @extractRegressionSetting , designMatrix, responseVector
77import .. OrdinaryLeastSquares: residuals, coef, olsf!, olsf
88
9- import Distributions: sample!, mean
9+ import Distributions: sample!
10+ import LinearAlgebra: mul!
1011
1112"""
1213
4243function iterateCSteps (
4344 X:: AbstractMatrix{Float64} ,
4445 y:: AbstractVector{Float64} ,
45- subsetindices:: Array {Int,1 } ,
46+ subsetindices:: AbstractVector {Int} ,
4647 h:: Int ; eps:: Float64 = 0.01 , maxiter:: Int = 10000
4748)
48- n = length (y )
49+ n, p = size (X )
4950 oldobjective:: Float64 = Inf64
5051 objective:: Float64 = Inf64
5152 iter:: Int = 0
5253 sortedresindices = Array {Int} (undef, n)
53- tempbetas = zeros (size (X, 2 ))
54- absres = zeros (n)
54+ tempbetas = Vector {Float64} (undef, p)
55+ fitted = Vector {Float64} (undef, n)
56+ absres = Vector {Float64} (undef, n)
57+ workingsubset = copy (subsetindices)
58+ if h > length (workingsubset)
59+ resize! (workingsubset, h)
60+ end
61+ workingsubsetlen = length (subsetindices)
5562 while iter < maxiter
56- olsf! (view (X, subsetindices, :), view (y, subsetindices), tempbetas)
57- absres .= abs .(y - X * tempbetas)
63+ activeindices = view (workingsubset, 1 : workingsubsetlen)
64+ olsf! (view (X, activeindices, :), view (y, activeindices), tempbetas)
65+ mul! (fitted, X, tempbetas)
66+ @inbounds for i in eachindex (y)
67+ absres[i] = abs (y[i] - fitted[i])
68+ end
5869 sortperm! (sortedresindices, absres)
59- subsetindices = view (sortedresindices, 1 : h)
60- objective = sum (view (sort! (absres .^ 2.0 ), 1 : h))
70+ objective = 0.0
71+ @inbounds for i = 1 : h
72+ idx = sortedresindices[i]
73+ workingsubset[i] = idx
74+ objective += abs2 (absres[idx])
75+ end
76+ workingsubsetlen = h
6177 if abs (oldobjective - objective) < eps
6278 break
6379 end
6480 oldobjective = objective
6581 iter += 1
6682 end
67- return (objective, subsetindices)
83+ resize! (workingsubset, workingsubsetlen)
84+ return (objective, workingsubset)
6885end
6986
7087
@@ -83,9 +100,15 @@ function iterateCSteps(
83100 h:: Int ; eps:: Float64 = 0.01 , maxiter:: Int = 10000
84101)
85102 p = size (X, 2 )
86- res = y - X * initialBetas
87- sortedresindices = sortperm (abs .(res))
88- subsetindices = sortedresindices[1 : p]
103+ res = Vector {Float64} (undef, length (y))
104+ mul! (res, X, initialBetas)
105+ @inbounds for i in eachindex (y)
106+ res[i] = abs (y[i] - res[i])
107+ end
108+ sortedresindices = Array {Int} (undef, length (y))
109+ sortperm! (sortedresindices, res)
110+ subsetindices = Vector {Int} (undef, p)
111+ copyto! (subsetindices, 1 , sortedresindices, 1 , p)
89112 return iterateCSteps (X, y, subsetindices, h, eps = eps, maxiter = maxiter)
90113end
91114
@@ -149,7 +172,7 @@ function lts(X::AbstractMatrix{Float64}, y::AbstractVector{Float64}; iters=nothi
149172 h = Int (floor ((n + p + 1.0 ) / 2.0 ))
150173
151174 if isnothing (iters)
152- iters = minimum ([ 5 * p, 3000 ] )
175+ iters = min ( 5 * p, 3000 )
153176 end
154177
155178 allindices = collect (1 : n)
@@ -175,11 +198,36 @@ function lts(X::AbstractMatrix{Float64}, y::AbstractVector{Float64}; iters=nothi
175198 end
176199
177200 ltsbetas = olsf (view (X, besthsubset, :), view (y, besthsubset))
178- ltsres = y - X * ltsbetas
179- ltsS = sqrt (sum ((ltsres .^ 2.0 )[1 : h]) / (h - p))
180- ltsresmean = mean (ltsres[besthsubset])
181- ltsScaledRes = (ltsres .- ltsresmean) / ltsS
182- outlierindices = filter (i -> abs (ltsScaledRes[i]) > crit, 1 : n)
201+ ltsres = Vector {Float64} (undef, n)
202+ mul! (ltsres, X, ltsbetas)
203+ @inbounds for i in eachindex (y)
204+ ltsres[i] = y[i] - ltsres[i]
205+ end
206+
207+ ltsSsum = 0.0
208+ @inbounds for i = 1 : h
209+ ltsSsum += abs2 (ltsres[i])
210+ end
211+ ltsS = sqrt (ltsSsum / (h - p))
212+
213+ ltsresmean = 0.0
214+ @inbounds for idx in besthsubset
215+ ltsresmean += ltsres[idx]
216+ end
217+ ltsresmean /= h
218+
219+ ltsScaledRes = Vector {Float64} (undef, n)
220+ @inbounds for i in eachindex (ltsres)
221+ ltsScaledRes[i] = (ltsres[i] - ltsresmean) / ltsS
222+ end
223+
224+ outlierindices = Int[]
225+ sizehint! (outlierindices, n)
226+ @inbounds for i = 1 : n
227+ if abs (ltsScaledRes[i]) > crit
228+ push! (outlierindices, i)
229+ end
230+ end
183231
184232 result = Dict (
185233 " objective" => bestobjective,
0 commit comments