2016-11-30 7 views
-2
f <- function(n){ 
    s <- 0 
    for (i in 1:n){ 
    s <- s + (i/2) 
    } 
    print(s) 
} 

Хитрость, конечно, что s рекурсивно зависит от предыдущего цикла ..Как бы вы процитировали этот цикл for в R (s + = i/2)?

[EDIT]

Спасибо за ваши ответы. Я просто пытался проверить прирост производительности с помощью векторизации в R по сравнению с циклами.

С п = 1000000000 выше функция принимает 287 секунд, в то время как sum((1:n)/2) и sum(seq_len(n)/2) возвращают мне ошибку, что система «не может выделить вектор размером 7,5 Гб»

Для сравнения той же функции (с п = 1000000000) в Julia занимает 38 секунд (0,87, определяя тип s), в C++ 2.48 секунды/0.87 компиляция с оптимизацией и в Python 98 секунд/0.88 с использованием декораторов numba.

+3

Разве это не '' сумма (1: n)/2'? – Psidom

+2

Почему вы хотите векторизовать цикл? это просто n * (n + 1)/4, может быть вычислено в постоянное время. –

+0

Это также зависит от вашей машины, я выполнил 'sum (seq_len (n)/2)' с 'n = 1000000000', и я получил' 2.5e + 17' как ответ без каких-либо ошибок. Время, затрачиваемое в среднем на 5.5 секунд. – 989

ответ

7

Вы можете сделать это (в случае n>0):

sum(seq_len(n)/2) 

f(10) 
#[1] 27.5 

sum(seq_len(10)/2) 
#[1] 27.5 

В случае n<0:

sum((1:n)/2) 

n <- -11 
f(n) 
#[1] -32.5 

sum((1:n)/2) 
#[1] -32.5 

Только быстрый бенчмаркинга:

library(microbenchmark) 
n <- 10000 

f1 <- function(n) sum(seq_len(n)/2) 
f2 <- function(n){ s <- 0;for (i in 1:n){s <- s + (i/2);};s} 

f1(n)==f2(n) 
# [1] TRUE 
microbenchmark(f1(n), f2(n)) 

# Unit: microseconds 
    # expr  min  lq  mean median  uq  max neval 
# f1(n) 20.733 22.235 27.51751 22.836 24.639 82.028 100 
# f2(n) 3971.008 4275.383 4517.52582 4484.510 4648.867 5867.272 100 
+0

. На ваше редактирование уже ответили в другом сообщении. – akrun

+0

@PierreLafortune лучший способ выразить это будет «это будет ошибка с отрицательными номерами, в то время как исходный код будет ** давать неверные результаты молча **. Потому что я буду держать вас в пари, какие деньги OP просто не учитывал отрицательные числа –

+0

@ 989: Я бы просто придерживался 'seq_len'. –

2

это то, что вы имеете в виду?

n<-10 
print(sum((1:n)/2))