Сумма может быть увеличена до
## S1 = c1
## S2 = S1 * c2 - c3 = c1 * c2 - c3
## S3 = S2 * c2 - c3 = c1 *c2^2 - c3 *c2 - c3
## S4 = S3 * c2 - c3 = c1 *c2^3 - c3 *c2^2 - c3 * c2 - c3
и реализовано как
f5 <- function(n) {
c1 <- 3
c2 <- 1 + 0.05 / 12
c3 <- 50
p <- cumprod(c(1, rep(c2, n - 1)))
c1 * p - c3 * cumsum(c(0, p[-length(p)]))
}
По сравнению с my()
реализовано как
my <- function(n) {
cost1 <- 3
cost2 <- 0.05
cost3 <- 50
cc <- (1 + cost2/12)
r <- vector('numeric', length = n)
r[1] <- cost1
for (j in 2:n)
r[j] <- r[j - 1] * cc - cost3
r
}
у нас есть числовая эквивалентность и улучшенная производительность
> n <- 1e4
> all.equal(my(n), f5(n))
[1] TRUE
> microbenchmark(my(n), f5(n), times=5)
Unit: microseconds
expr min lq mean median uq max neval
my(n) 2495.459 2504.392 2516.5754 2505.541 2529.837 2547.648 5
f5(n) 559.813 561.670 569.0204 563.739 565.325 594.555 5
но числовые проблемы (также для всех других реализаций) в целом n
> x = f5(1e6)
> x[which.min(x) + (-3):3]
[1] -1.778181e+308 -1.785590e+308 -1.793030e+308 -Inf -Inf
[6] -Inf -Inf
> which.min(x)
[1] 168445