R - рекурсивная дихотомия над рядом точек данных - PullRequest
3 голосов
/ 15 апреля 2020
# start with 3 points
# calculate their mid point, assumming normal distribution
start_init <- 10
mid_init <- 20
end_init <- 50
start <- start_init
end <- mid_init
mid_1 <- mean(c(start,end))

start <- mid_init
end <- end_init
mid_2 <- mean(c(start,end))

# now we have 3 points
c(start_init, mid_1, mid_init, mid_2, end_init)

# further calculate the mid points between
start <- start_init
end <- mid_1
mid_1_1 <- mean(c(start,end))

start <- mid_1
end <- mid_init
mid_1_2 <- mean(c(start,end))

start <- mid_init
end <- mid_2
mid_2_1 <- mean(c(start,end))

start <- mid_2
end <- end_init
mid_2_2 <- mean(c(start,end))

# now we have 9 data points
res <- c(start_init, mid_1_1 ,mid_1, mid_1_2, mid_init, mid_2_1, mid_2, mid_2_2, end_init)

Я хочу сжать код выше, чтобы можно было определить рекурсивную глубину. Например, для глубины, равной 1, нам нужно сгенерировать 1 новую точку для всей доступной комбинации из 2 последовательных точек.

Как показано выше, мы начинаем с 3 точек (A, B, C), поэтому с глубиной, равной 1, у нас будет не более 2 дополнительных новых точек, которые находятся между A и B, а также B и C.

Ответы [ 2 ]

2 голосов
/ 15 апреля 2020

Используя пользовательскую вспомогательную функцию cross_vectors, вы можете создать другую пользовательскую функцию (я назвал ее recursive_dichotomy), которая использует пакет zoo для вычисления среднего между двумя последовательными точками.

Это код

# helper function
cross_vectors <- function(x, y){
    c(x, y)[order(c(ceiling(seq_along(x) / 1), seq_along(y)))]
}

recursive_dichotomy <- function(v, depth){
  # initialization
  require(zoo)
  current_depth <- 1

  # while cycle for the depth of the splitting
  while(current_depth <= depth){
    v <- cross_vectors(v, rollmean(v, k = 2))
    current_depth <- current_depth + 1
  }

  return(v)
}

Выход

recursive_dichotomy(c(10, 20, 50), depth = 2)
# [1] 10.0 12.5 15.0 17.5 20.0 27.5 35.0 42.5 50.0
1 голос
/ 15 апреля 2020

Вот еще одна альтернатива, которая выглядит (после нескольких проб и ошибок) действительной:

ff = function(x, depth)
{
    nbetween = 2 ^ depth
    means = (x[-1] - x[-length(x)]) / nbetween
    diffs = c(x[1], rep(means, each = nbetween))
    return(cumsum(diffs))
}

ff(c(10, 20, 50), 2)
#[1] 10.0 12.5 15.0 17.5 20.0 27.5 35.0 42.5 50.0
ff(c(10, 20, -5, 5), 1)
#[1] 10.0 15.0 20.0  7.5 -5.0  0.0  5.0
ff(c(10, 20, -5, 5), 2)
#[1] 10.00 12.50 15.00 17.50 20.00 13.75  7.50  1.25 -5.00 -2.50  0.00  2.50  5.00
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...