@@ -144,3 +144,36 @@ function kde(data::RealVector; bandwidth=default_bandwidth(data), kernel=Normal,
144
144
dist = kernel_dist (kernel,bandwidth)
145
145
kde (data,dist;boundary= boundary,npoints= npoints)
146
146
end
147
+
148
+ # change the M to some larger value to get better precision of lscv
149
+ function bandwidth_lscv (data:: RealVector ; kernel:: DataType = Normal, M= 1024 )
150
+ n= length (data)
151
+ h0= default_bandwidth (data)
152
+ hlb = h0/ sqrt (n)
153
+ hub = sqrt (n)* h0
154
+ xlb, xub = extrema (data)
155
+ midpoints = kde_range ((xlb- 4 * h0, xub+ 4 * h0), M)
156
+
157
+ k = tabulate (data, midpoints)
158
+ # the ft here is M/ba*sqrt(2pi) * u(s), it is M times the Yl in Silverman's book
159
+ Yl2 = abs2 (rfft (k. density)/ M)
160
+
161
+ ba = step (k. x)* M # the range b -a
162
+ c = - twoπ/ ba
163
+
164
+ return Optim. optimize (h -> lscv (h, Yl2, kernel, c, ba, n,M), hlb, hub). minimum
165
+ end
166
+
167
+ # Silverman's book use the special case of gaussian kernel. Here the method is generalized to any symmetric kernel
168
+ function lscv (bandwidth:: Real , Yl2:: RealVector , kernel:: DataType , c:: Real , ba:: Real , n:: Int ,M:: Int )
169
+ dist = kernel_dist (kernel,bandwidth)
170
+ zeta_star = zeros (length (Yl2)- 1 )
171
+ # M is even, length(Yl2) = M/2+1 and Yl2 =[y[l]^2 for l=0 :1: M/2]
172
+ for j = 1 : length (Yl2)- 1
173
+ ksl = real (cf (dist,j* c))
174
+ zeta_star[j] = Yl2[j+ 1 ] * (ksl * ksl - 2 * ksl)
175
+ end
176
+ # Correct the error in silverman's book
177
+ # ∫ (cf^2 -2cf)u(s)²ds <- ∑(cf^2 - 2cf)*Yl2*ba²/2pi * c
178
+ sum (zeta_star) * abs (c)* ba* ba/ (2 * pi ) + pdf (dist, 0.0 )/ n
179
+ end
0 commit comments