Могу ли я создать версию функции логистической карты без цикла for? - PullRequest
0 голосов
/ 03 октября 2018

У меня есть функция R для вычисления логистической карты , как показано ниже, с использованием цикла for.Но есть ли способ изменить его (например, векторизовать), чтобы он не использовал цикл?

logistic_map <- function(x,   # starting condition
                         r,   # rate parameter
                         N) { # number of iterations
    results <- numeric(length = N + 1)
    results[1] <- x
    for (i in seq_len(N)) {
        results[i + 1] <- r * results[i] * (1 - results[i])
    }

    data.frame(i = c(0, seq_len(N)), 
               x = results)
}

Я рассмотрел семейство функций apply() и функций в purrr, но я изо всех сил пытаюсь определить, возможно ли это вообще.Я испытываю желание сделать вывод, что это невозможно, просто потому, что каждый шаг полностью зависит от предыдущего, но вполне возможно, что есть элегантное решение, которое я не смог найти.

Могу ли ясделать это без цикла for?

Ответы [ 2 ]

0 голосов
/ 03 октября 2018

Конечно, вы можете, вот подход for без петель без сокращения, использующий только базовую R:

> v = {r=2.8;Reduce(function(a,b){xn=a[length(a)];b=r*xn*(1-xn);c(a,b)},rep(0,100),init=0.5)}
> v
  [1] 0.5000000 0.7000000 0.5880000 0.6783168 0.6109687 0.6655206 0.6232882
  [8] 0.6574401 0.6305953 0.6522456 0.6350996 0.6488947 0.6379250 0.6467347
 [15] 0.6397130 0.6453448 0.6408497 0.6444518 0.6415743 0.6438788 0.6420369

Вопрос о том, должен ли - это другой вопрос.Если вы делаете это, чтобы попытаться получить некоторую скорость, то сначала вы должны научиться тестировать, а затем посмотреть, будет ли это быстрее.Использование for циклов - это одна из вещей, они говорят вам, что это плохо, но не слушайте их - иногда for циклы быстрее, чем любой из их пакетов.

Чтобы получить более фундаментальное значение, одно из свойств рекуррентных отношений, подобных фракталам, состоит в том, что они, как правило, не имеют решений в замкнутой форме.Решение в закрытой форме позволит вам вычислить x[i] без вычисления сначала x[i-1] и, следовательно, будет тривиально векторизованным.Для логистической карты Википедия говорит нам: https://en.wikipedia.org/wiki/Logistic_map, что только для определенных значений r существуют решения в закрытой форме.За пределами этих значений вы должны выполнять итеративные вычисления.

0 голосов
/ 03 октября 2018
library(Rcpp)

cppFunction('NumericVector cpp_loop (NumericVector x, double r) {
  int n = x.size(), i = 0; n--;
  for (; i < n; i++) x[i + 1] = r * x[i] * (1 - x[i]);
  return x;
  }')

logistic_map <- function(x,   # starting condition
                         r,   # rate parameter
                         N) { # number of iterations
    results <- numeric(length = N + 1)
    results[1] <- x
    cpp_loop(results, r)

    data.frame(i = c(0, seq_len(N)), 
               x = results)
}

logistic_map(2, 0.2, 100)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...