对于几何级数,连续值的比率是恒定的,因此将该比率乘以当前值可以得到下一个值。
为了检查序列是否是几何的,我们可以取序列中每对连续值的比率,如果这些比率都相等,则序列是几何的。因为这相当于检查它们的方差是否为零,我们可以使用var 轻松完成。由于浮点运算不精确,我们检查方差是否小于eps。
请注意,is.geo 对于长度为 1 或 2 的序列返回 NA,如果 is.geo 不返回 TRUE,nextValue 将返回 NA。
nextValue <- function(x) {
if (!isTRUE(is.geo(x))) NA
else {
y <- tail(x, 2)
y[2]^2 / y[1]
}
}
is.geo <- function(x, eps = 1e-5) var(x[-1] / x[-length(x)]) < eps
测试
使用最后注释中定义的m,我们可以将下一个值作为新列附加到它:
cbind(m, apply(m, 1, nextValue))
给予:
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
[1,] 1 2 4 8 16 32 64 128
[2,] 2 4 8 16 32 64 128 256
[3,] 3 6 12 24 48 96 192 384
[4,] 1 3 9 27 81 243 729 2187
[5,] 2 6 18 54 162 486 1458 4374
[6,] 3 9 27 81 243 729 2187 6561
我们也可以测试m的每一行来检查是否是几何的:
apply(m, 1, is.geo)
## [1] TRUE TRUE TRUE TRUE TRUE TRUE
is.geo(c(1, 2, 4, 12))
## [1] FALSE
使用 lm
如果通过问题中显示的链接的方法意味着使用lm,那么我们可以使用lm,如果该系列是严格正的,请注意这种几何级数的log是算术的,所以我们可以将系列的对数拟合为 1, 2, 3, ... 。如果偏差为零时发生的残差为零,则它满足这一点。
fit <- function(x) {
ix <- seq_along(x)
lm(log(x) ~ ix)
}
nextValue2 <- function(x) {
if (!isTRUE(is.geo2(x))) NA
else exp( predict(fit(x), list(ix = length(x) + 1)) )
}
is.geo2 <- function(x, eps = 1.e-5) {
if (length(x) <= 2) NA
else deviance(fit(x)) < eps
}
注意
m <- matrix(c(1L, 2L, 3L, 1L, 2L, 3L, 2L, 4L, 6L, 3L, 6L, 9L, 4L,
8L, 12L, 9L, 18L, 27L, 8L, 16L, 24L, 27L, 54L, 81L, 16L, 32L,
48L, 81L, 162L, 243L, 32L, 64L, 96L, 243L, 486L, 729L, 64L, 128L,
192L, 729L, 1458L, 2187L), 6)