@@ -256,7 +256,8 @@ function stationary_distribution(::CosineKernel, ::SArrayStorage{T}) where {T<:R
256
256
return Gaussian (m, P)
257
257
end
258
258
259
- # Approximate Periodic Kernel
259
+ # ApproxPeriodicKernel
260
+
260
261
# The periodic kernel is approximated by a sum of cosine kernels with different frequencies.
261
262
struct ApproxPeriodicKernel{N,K<: PeriodicKernel } <: KernelFunctions.SimpleKernel
262
263
kernel:: K
@@ -279,53 +280,37 @@ function Base.show(io::IO, κ::ApproxPeriodicKernel{N}) where {N}
279
280
return print (io, " Approximate Periodic Kernel, (r = $(only (κ. kernel. r)) ) approximated with $N cosine kernels" )
280
281
end
281
282
282
- function lgssm_components (approx:: ApproxPeriodicKernel{N} , t:: Union{StepRangeLen, RegularSpacing} , storage:: StorageType{T} ) where {N,T<: Real }
283
- Fs, Hs, ms, Ps = _init_periodic_kernel_lgssm (approx. kernel, storage, N)
284
- nt = length (t)
285
- As = map (F -> Fill (time_exp (F, T (step (t))), nt), Fs)
286
- return _reduce_sum_cosine_kernel_lgssm (As, Hs, ms, Ps, N, nt, T)
287
- end
288
- function lgssm_components (approx:: ApproxPeriodicKernel{N} , t:: AbstractVector{<:Real} , storage:: StorageType{T} ) where {N,T<: Real }
289
- Fs, Hs, ms, Ps = _init_periodic_kernel_lgssm (approx. kernel, storage, N)
290
- t = vcat ([first (t) - 1 ], t)
291
- nt = length (diff (t))
292
- As = _map (F -> _map (Δt -> time_exp (F, T (Δt)), diff (t)), Fs)
293
- return _reduce_sum_cosine_kernel_lgssm (As, Hs, ms, Ps, N, nt, T)
294
- end
283
+ # Can't use approx periodic kernel with static arrays -- the dimensions become too large.
284
+ _ap_error () = throw (error (" Unable to construct an ApproxPeriodicKernel for SArrayStorage" ))
285
+ to_sde (:: ApproxPeriodicKernel , :: SArrayStorage ) = _ap_error ()
286
+ stationary_distribution (:: ApproxPeriodicKernel , :: SArrayStorage ) = _ap_error ()
295
287
296
- function _init_periodic_kernel_lgssm (kernel:: PeriodicKernel , storage, N:: Int = 7 )
297
- r = kernel. r
298
- l⁻² = inv (4 * only (r)^ 2 )
299
-
288
+ function to_sde (:: ApproxPeriodicKernel{N} , storage:: ArrayStorage{T} ) where {T<: Real , N}
289
+
290
+ # Compute F and H for component processes.
300
291
F, _, H = to_sde (CosineKernel (), storage)
301
292
Fs = ntuple (N) do i
302
293
2 π * (i - 1 ) * F
303
294
end
304
- Hs = Fill (H, N)
305
295
296
+ # Combine component processes into a single whole.
297
+ F = block_diagonal (collect .(Fs)... )
298
+ q = zero (T)
299
+ H = repeat (collect (H), N)
300
+ return F, q, H
301
+ end
302
+
303
+ function stationary_distribution (kernel:: ApproxPeriodicKernel{N} , storage:: ArrayStorage{<:Real} ) where {N}
306
304
x0 = stationary_distribution (CosineKernel (), storage)
307
- ms = Fill (x0. m, N)
308
- P = x0. P
305
+ m = collect (repeat (x0. m, N))
306
+ r = kernel. kernel. r
307
+ l⁻² = inv (4 * only (r)^ 2 )
309
308
Ps = ntuple (N) do j
310
309
qⱼ = (1 + (j != = 1 ) ) * besseli (j - 1 , l⁻²) / exp (l⁻²)
311
- qⱼ * P
312
- end
313
-
314
- Fs, Hs, ms, Ps
315
- end
316
-
317
- function _reduce_sum_cosine_kernel_lgssm (As, Hs, ms, Ps, N, nt, T)
318
- as = Fill (Fill (Zeros {T} (size (first (first (As)), 1 )), nt), N)
319
- Qs = _map ((P, A) -> _map (A -> Symmetric (P) - A * Symmetric (P) * A' , A), Ps, As)
320
- Hs = Fill (vcat (Hs... ), nt)
321
- h = Fill (zero (T), nt)
322
- As = _map (block_diagonal, As... )
323
- as = - map (vcat, as... )
324
- Qs = _map (block_diagonal, Qs... )
325
- m = reduce (vcat, ms)
326
- P = block_diagonal (Ps... )
327
- x0 = Gaussian (m, P)
328
- return As, as, Qs, (Hs, h), x0
310
+ return qⱼ * x0. P
311
+ end
312
+ P = collect (block_diagonal (Ps... ))
313
+ return Gaussian (m, P)
329
314
end
330
315
331
316
# Constant
0 commit comments