Для геометрического ряда отношение последовательных значений является постоянным, поэтому умножение этого отношения на текущее значение дает следующее значение.
Чтобы проверить, является ли ряд геометрическим, мы можем взять отношение каждой последующей пары значений в ряду, и если все эти отношения равны, ряд является геометрическим. Поскольку это эквивалентно проверке, равна ли их дисперсия нулю, мы можем легко сделать это, используя var
. Поскольку арифметика с плавающей запятой не является точной, мы проверяем, меньше ли дисперсия eps
.
Обратите внимание, что is.geo
возвращает NA для серии длиной 1 или 2, а nextValue
возвращает NA, если is.geo
не возвращает TRUE.
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
, если ряд строго положителен, отметив, что 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)
person
G. Grothendieck
schedule
25.08.2019