2
votes

Somme sans boucles

J'ai la double sommation suivante: âˆ'10, i = 1 âˆ'i, j = 1 (i ^ 5 / (10 + j ^ i)) Double sommation

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 = rep(1:10, each=5)
    j = rep(i, 10) 
    sum(i^5/(10+j^i))

entrez la description de l'image ici

ou

    i <- seq(1, 10, 1) 
    j <- seq(1, i, 1)
    denominators <- 10+j^i
    fractions <- (i^5)/denominators
    sum(fractions) 

r

0 commentaires

4 Réponses :


3
votes

Faire une fonction de la somme intérieure:

n <- 10
x <- outer(1:n, 1:n, function(i,j) i^5 / (10 + j^i))
sum(x[!upper.tri(x)])

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 j ne dépasse pas i :

f <- Vectorize(function(i) {
         j <- 1:i
         sum(i^5 / (10 + j^i))
     })

Pour sa compacité et sa simplicité, cependant, c'est une bonne technique à connaître.


2 commentaires

Lorsque j'exécute ce code, il indique erreur:> x <- externe (1: n, 1: n, fonction (i, j) i ^ 5 / (10 + j ^ i)) Erreur en externe (1: n, 1 : n, fonction (i, j) i ^ 5 / (10 + j ^ i)): objet 'n' non trouvé> sum (x [! upper.tri (x)]) Erreur: objet 'x' non trouvé . Est-ce que j'ai fait quelque chose de mal?


Désolé (vous n'avez rien fait de mal) - J'ai laissé tomber une parenthèse lors du collage. Je l'ai restauré. Le code produit externe exigeait que la variable n soit définie sur 10 ; J'ai explicitement remis cette ligne.



3
votes

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


1 commentaires

Intéressant ... mais la mise à l'échelle vers des sommes plus importantes est extrêmement médiocre.



1
votes

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


0 commentaires

1
votes

Cela a été assez bien répondu maintenant, mais je vais jeter une autre solution dans le mix avec une technique différente, en utilisant Map() / Reduce() :

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

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:

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


1 commentaires

Merci beaucoup pour vos efforts et votre solution, j'apprécie vraiment de voir les différentes façons de résoudre ce problème!