I need to calculate this
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.
So the double summation ∑ i = 1 m ∑ j = 1 n f ( i, j) is nothing but the sum of all elements of the above matrix. There is no need to put the inner sigma symbol in brackets. We can just simply write ∑ i = 1 m ( ∑ j = 1 n f ( i, j)), without brackets as ∑ i = 1 m ∑ j = 1 n f ( i, j).
Commutativity: The double summation ∑ i = 1 m ∑ j = 1 n f ( i, j) is commutative, i.e. ∑ i = 1 m ∑ j = 1 n f ( i, j) = ∑ j = 1 n ∑ i = 1 m f ( i, j). This is quite evident if we take a good look at the matrix form.
The sum () method of Double class returns the sum of two double arguments same as the operation performed by '+' operator. The sum () method returns the sum of a and b. Scanner scanner= new Scanner (System.in);
So the double summation ∑ i = 1 m ∑ j = 1 n f ( i, j) is nothing but the sum of all elements of the above matrix. There is no need to put the inner sigma symbol in brackets.
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
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With