Somme sans boucles
J'ai la double sommation suivante: ∑10, i = 1 ∑i, j = 1 (i ^ 5 / (10 + j ^ i))
Je suis assez perdu avec cet exercice, j'ai essayé le code suivant mais il renvoie une erreur tout en me donnant un numéro - à peu près sûr que ce n'est pas correct. Toute aide est grandement appréciée!
i <- seq(1, 10, 1)
j <- seq(1, i, 1)
denominators <- 10+j^i
fractions <- (i^5)/denominators
sum(fractions)
ou
i = rep(1:10, each=5)
j = rep(i, 10)
sum(i^5/(10+j^i))
Réponses
Faire une fonction de la somme intérieure:
f <- Vectorize(function(i) {
j <- 1:i
sum(i^5 / (10 + j^i))
})
En le vectorisant, vous pouvez l'appliquer à des tableaux, où il fonctionnera composant par composant: c'est ce que la somme externe sur i dit de faire. Ainsi, la valeur est
sum(f(1:10))
Une autre solution, gaspilleuse de RAM et un peu plus lente, exploite le produit externe pour calculer tous les termes de la double somme dans une matrice. Vous devez extraire les termes pour lesquels jne dépasse pas i:
n <- 10
x <- outer(1:n, 1:n, function(i,j) i^5 / (10 + j^i))
sum(x[!upper.tri(x)])
Pour sa compacité et sa simplicité, cependant, c'est une bonne technique à connaître.
Vous pouvez développer toutes les combinaisons i / j possibles, puis résumer tous les termes
i <- 1:10
ii <- rep(i, i)
jj <- unlist(sapply(i, function(x) seq(1,x)))
sum(ii^5/(10+jj^ii))
# [1] 20835.22
tout dans r est vectorisé:
i <- seq(10)
j <- sequence(i)
i_use <- rep(i,i)
sum(i_use^5/(10 + j^i_use))
[1] 20835.22
Cela a été assez bien répondu maintenant, mais je vais jeter une autre solution dans le mélange avec une technique différente, en utilisant Map()/ Reduce():
i <- seq_len(10)
j <- lapply(i, seq_len)
Reduce("sum", Map(function(i, j) i^5 / (10 + j^i), i, j))
#> [1] 20835.22
Et par curiosité, repères des réponses actuellement publiées. Définitions:
sum_vectorize <- function(n) {
f <- Vectorize(function(i) {
j <- 1:i
sum(i^5 / (10 + j^i))
})
sum(f(1:n))
}
sum_outer <- function(n) {
x <- outer(1:n, 1:n, function(i,j) i^5 / (10 + j^i))
sum(x[!upper.tri(x)])
}
sum_sapply <- function(n) {
i <- 1:n
ii <- rep(i, i)
jj <- unlist(sapply(i, function(x) seq(1,x)))
sum(ii^5/(10+jj^ii))
}
sum_sequence <- function(n) {
i <- seq(n)
j <- sequence(i)
i_use <- rep(i,i)
sum(i_use^5/(10 + j^i_use))
}
sum_reduce <- function(n) {
i <- seq_len(n)
j <- lapply(i, seq_len)
Reduce("sum", Map(function(i, j) i^5 / (10 + j^i), i, j))
}
Et les résultats:
bench::press(
n = c(10, 1000),
{
bench::mark(
sum_vectorize(n),
sum_outer(n),
sum_sapply(n),
sum_sequence(n),
sum_reduce(n)
)
}
)
#> Running with:
#> n
#> 1 10
#> 2 1000
#> Warning: Some expressions had a GC in every iteration; so filtering is disabled.
#> # A tibble: 10 x 7
#> expression n min median `itr/sec` mem_alloc `gc/sec`
#> <bch:expr> <dbl> <bch:tm> <bch:tm> <dbl> <bch:byt> <dbl>
#> 1 sum_vectorize(n) 10 59.1us 69.4us 10307. 39.07KB 14.8
#> 2 sum_outer(n) 10 18.1us 21.4us 35014. 49.8KB 7.00
#> 3 sum_sapply(n) 10 69.5us 88.8us 9044. 1.48KB 14.7
#> 4 sum_sequence(n) 10 14.2us 16.3us 45303. 6.89KB 4.53
#> 5 sum_reduce(n) 10 32.6us 38.1us 20404. 0B 19.1
#> 6 sum_vectorize(n) 1000 105ms 118.1ms 8.60 5.85MB 0
#> 7 sum_outer(n) 1000 303.3ms 319.3ms 3.13 47.7MB 4.70
#> 8 sum_sapply(n) 1000 148.6ms 154.6ms 6.49 13.44MB 4.87
#> 9 sum_sequence(n) 1000 131.5ms 142.1ms 7.01 11.46MB 1.75
#> 10 sum_reduce(n) 1000 107.5ms 115ms 8.32 5.85MB 1.66