5

I need to calculate this

enter image description here

where x is a vector of length n and f is a function.

What is the most efficient calculation for this in R?

One method is a double for loop, but that is obviously slow.

Ronak Shah
  • 377,200
  • 20
  • 156
  • 213
Janus
  • 165
  • 4
  • You can simplify it to just `sum^n_{i = 1} f(x_i, x_n)` since j \geq n and length(x) = n implies the inner sum is redundant. – Hugh Sep 14 '19 at 13:15

2 Answers2

3

One fast way to do is the following:

Assume we have this vector:

x = c(0,1,2)

i.e. n=3, and assume f is a multiplication function:

Now, we use expand.grid.unique custom function which produces unique combinations within vector; in other words, it is similar to expand.grid base function but with unique combinations:

expand.grid.unique <- function(x, y, include.equals=FALSE)
{
    x <- unique(x)

    y <- unique(y)

    g <- function(i)
    {
        z <- setdiff(y, x[seq_len(i-include.equals)])

        if(length(z)) cbind(x[i], z, deparse.level=0)
    }

    do.call(rbind, lapply(seq_along(x), g))
}

In our vector case, when we cal expand.grid.unique(x,x), it produces the following result:

> expand.grid.unique(x,x)
     [,1] [,2]
[1,]    0    1
[2,]    0    2
[3,]    1    2

Let's assign two_by_two to it:

two_by_two <- expand.grid.unique(x,x)

Since our function is assumed to be multiplication, then we need to calculate sum-product, i.e. dot product of first and second columns of two_by_two. For this we need %*% operator:

output <- two_by_two[,1] %*% two_by_two[,2]
> output
     [,1]
[1,]    2
Vitali Avagyan
  • 1,193
  • 1
  • 7
  • 17
2

See ?combn

x <- 0:2
combn(x, 2)

# unique combos
     [,1] [,2] [,3]
#[1,]    0    0    1
#[2,]    1    2    2

sum(combn(x, 2))
#[1] 6

combn() creates all the unique combinations. If you have a function that you want to sum, you can add a FUN to the call:

random_f <- function(x){x[1] + 2 * x[2]}

combn(x, 2, FUN = random_f)
#[1] 2 4 5

sum(combn(x, 2, FUN = random_f))
#[1] 11
Cole
  • 11,130
  • 1
  • 9
  • 24