+ if (simtype != "endo")
+ {
+ h_exo = ifelse(simtype=="mix", h[2], h)
+
+ M = matrix( nrow=1+length(fdays), ncol=1+length(data$getExo(today)) )
+ M[1,] = c( data$getLevel(today), as.double(data$getExo(today)) )
+ for (i in seq_along(fdays))
+ M[i+1,] = c( data$getLevel(fdays[i]), as.double(data$getExo(fdays[i])) )
+
+ sigma = cov(M) #NOTE: robust covariance is way too slow
+ # TODO: 10 == magic number; more robust way == det, or always ginv()
+ sigma_inv =
+ if (length(fdays) > 10)
+ solve(sigma)
+ else
+ MASS::ginv(sigma)
+
+ # Distances from last observed day to days in the past
+ distances2 = sapply(seq_along(fdays), function(i) {
+ delta = M[1,] - M[i+1,]
+ delta %*% sigma_inv %*% delta
+ })
+
+ sd_dist = sd(distances2)
+ if (sd_dist < .25 * sqrt(.Machine$double.eps))
+ {
+# warning("All computed distances are very close: stdev too small")
+ sd_dist = 1 #mostly for tests... FIXME:
+ }
+ simils_exo =
+ if (kernel=="Gauss")
+ exp(-distances2/(sd_dist*h_exo^2))
+ else
+ {
+ # Epanechnikov
+ u = 1 - distances2/(sd_dist*h_exo^2)
+ u[abs(u)>1] = 0.
+ u
+ }
+ }