I have following double summation: ∑10,i=1 ∑i,j=1 (i^5/(10+j^i))
I am quite lost with this exercise, I tried the following code but I it returns an error although giving
This has been fairly thoroughly answered by now, but I’ll throw another
solution in the mix with a different technique, using 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
And out of curiosity, benchmarks of the currently posted answers. Definitions:
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))
}
And the results:
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
everything in r is vectorized:
i <- seq(10)
j <- sequence(i)
i_use <- rep(i,i)
sum(i_use^5/(10 + j^i_use))
[1] 20835.22
You could expand all the possible i/j combinations and then sum up all the terms
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
Make a function of the inner sum:
f <- Vectorize(function(i) {
j <- 1:i
sum(i^5 / (10 + j^i))
})
By vectorizing it you can apply it to arrays, where it will operate component by component: that's what the outer sum over i says to do. Thus, the value is
sum(f(1:10))
Another solution, wasteful of RAM and a bit slower, exploits the outer product to compute all the terms of the double sum in one matrix. You have to extract the terms for which j
does not exceed i
:
n <- 10
x <- outer(1:n, 1:n, function(i,j) i^5 / (10 + j^i))
sum(x[!upper.tri(x)])
For its compactness and simplicity, though, it's a good technique to know.