Matrix operation efficiency in R - r

I have 3 matrices X, K and M as follows.
x <- matrix(c(1,2,3,1,2,3,1,2,3),ncol=3)
K <- matrix(c(4,5,4,5,4,5),ncol=3)
M <- matrix(c(0.1,0.2,0.3),ncol=1)
Here is what I need to accomplish.
For example,
Y(1,1)=(1-4)^2*0.1^2+(1-4)^2*0.2^2+(1-4)^2*0.3^2
Y(1,2)=(1-5)^2*0.1^2+(1-5)^2*0.2^2+(1-5)^2*0.3^2
...
Y(3,2)=(3-5)^2*0.1^2+(3-5)^2*0.2^2+(3-5)^2*0.3^2
Currently I used 3 for loops to calculate the final matrix in R. But for large matrices, this is taking extremely long to calculate. And I also need to change the elements in matrix M to find the best value that produces minimal squared errors. Is there a better way to code it up, i.e. Euclidean norm?
for (lin in 1:N) {
for (col in 1:K) {
Y[lin,col] <- 0
for (m in 1:M){
Y[lin,col] <- Y[lin,col] + (X[lin,m]-K[col,m])^2 * M[m,1]^2
}
}
}
Edit:
I ended up using Rcpp to write the code in C++ and call it from R. It is significantly faster! It takes 2-3 seconds to fill up a 2000 * 2000 matrix.

Thank you. I was able to figure this out. The change made my calculation twice as fast as before. For anyone who may be interested, I replaced the last for loop for(m in 1:M) with the following:
Y[lin,col] <- norm(as.matrix((X[lin,]-K[col,]) * M[1,]),"F")^2
Note that I transposed the matrix M so that it has 3 columns instead of 1.

Related

Replicating R's prod() function in WinBUGS

Using WinBUGS, how can I calculate the product of all values in a single vector?
I have tried using a for loop over the same vector.
For example:
In R, if A <- [1,2,3,4], prod(A) = 24.
However,
in BUGS, if a <- 2 , and for (i in 1:n){ a <- a * A[i] }, this loop cannot work because 'a' is defined twice.
Hi and welcome to the site!
Remember that BUGS is a declarative syntax and not a programming language, so you cannot over-write variable values as you expect to be able to in a language such as R. So you need to create some intermediate nodes to do what you calculate.
If you have the following data:
A <- [1,2,3,4]
nA <- 4
Then you can include in your model:
sumlogA[1] <- 0
for(i in 1:nA){
sumlogA[i+1] <- sumlogA[i] + log(A[i])
}
prodA <- exp(sumlogA[nA+1])
Notice that I am working on the log scale and then take the exponent of the sum - this is mathematically equivalent to the product but is a much more computationally stable calculation.
Hope that helps,
Matt

How to write this For loops in R efficiently

I have a matrix X of nxp dimensions. Before I do some operations on it, I store it as X1. After these operations, I will check if any element of X is
negative, I replace it with its previous value from X1.
Currently, I am using the following code to do this.
X1 <- X
#some operations on X
for(i in 1:n){
for(j in 1:p){
if(X[i,j]< 0){
X[i,j]<-X1[i,j]
}
}
}
As n and p become large, this operation is taking a lot of time. Can you please suggest a efficient of writing the same.

Avoid nested for loops when summing over matrix indices

I have a fairly simply computation I need to do, but I cannot figure out how to do it in a way that is even close to efficient. I have a large nxn matrix, and I need to compute the following:
I'm still fairly inexperienced at coding, and so the only way that comes to my mind is to do the straightforward thing and use 3 for loops to move across the indexes:
sum=0
for(i in 1:n)
{
for(j in 1:n)
{
for(k in 1:n)
{
sum = sum + A[i,j]*A[j,k]
}
}
}
Needless to say, for any decent size matrix this takes forever to run. I know there must be a better, more efficient way to do this, but I cannot figure it out.
If you don't consider the k and i sums, you can realise that you are just doing the matrix product of A with itself. Such product in R is obtained through the %*% operator. After calculating this matrix, you just need to sum all the elements together:
sum(A %*% A)
should give the result you are seeking.

R: create new matrix with outcomes from mathematical operations within another matrix through loops

I am trying to generate a function that conducts various mathematical operations within a matrix and stores the outcomes of these operations in a new matrix with similar dimensions.
Here's an example matrix (a lot of silly computations in it to get sufficient variability in the data)
test<-matrix(1:290,nrow=10,ncol=29) ; colnames(test)<-1979+seq(1,29)
rownames(test)<-c("a","b","c","d","e","f","g","h","i","j")
test[,4]<-rep(8)
test[7,]<-seq(1,29)
test[c(3,5,9),]<-test[c(3,5,9),] * 1/2
test[,c(4,6,8,9,10,15,16,18)]<-test[,c(4,6,8,9,10,15,16,18)]*1/3
I want for instance to be able to calculate the difference between the value in (a,1999) and the average of the 3 values before (a, 1999). This needs to be flexible and for every rowname (firm) and every column (year).
The code I am trying to build looks something like this (I guess):
for(year in 1:29)
for (k in 1:10)
qw<-matrix((test[k, year] + 1/3*(- test[k, year-1] - test[k,year -2] - test[k, year-3])), nrow=10, ncol=29)
When I run it, this code generates a matrix but the value in that matrix is always the one for the last calculation (i.e. 20 in my example) while every matrix value should be stored in qw.
Any suggestions on how I can achieve this (maybe via an apply function)?
Thanks in advance
You are creating a matrix qw in every iteration. Each new matrix overwrites the previous one. Here's how to do what I think you would like to do, altough I didn't know how you want to handle the first 3 years.
qw <- matrix(nrow=10, ncol=29)
colnames(qw)<-1979+seq(1,29)
rownames(qw)<-c("a","b","c","d","e","f","g","h","i","j")
for(year in 4:29){
for (k in 1:10){
qw[k, year] <- (test[k, year] + 1/3*(- test[k, year-1] - test[k,year -2] - test[k, year-3]))
}
}
qw
In R, it is usually a bad idea to use loops, since there are much more efficient functions. Here is the R way of doing this, using the package zoo.
require(zoo)
qw <- matrix(nrow=10, ncol=29)
colnames(qw)<-1979+seq(1,29)
rownames(qw)<-c("a","b","c","d","e","f","g","h","i","j")
qw[,4:29] <- test[,4:29]-t(head(rollmean(t(test), 3),-1))
qw

R sum over infinite series loop?

I have this:
time=1:200
m=1:1000
sum[i]= sum(1/(1+2*m)^2)*exp( (-kappa*(1+2*m)^2 * pi^2 * time[i])/(z1^2))
I need to find the sum of the expression above for m=1:1000 and time=1:200
I have tried many variety of loop and cannot make it stick. I am even having trouble expressing this here....
This command will return a matrix:
time <- 1:200
m <- 1:1000
sapply(time,
function(time) sum(1/(1+2*m)^2)*exp((-kappa*(1+2*m)^2*pi^2*time)/(z1^2)))
In the matrix you will find the result for all combinations. The rows indicate the values of m, the columns indicate the values of time.
Maybe this will work:
sum<-0
time<-0
for(i in 1:200){
time<-time+1
m<-0
for(j in 1:1000){
m<-m+1
sum<-sum+(1/(1+2*m)^2)*exp((-kappa*(1+2*m)^2*pi^2*time)/(z1^2))
}
}
The loops should repeat the equation 200,000 times, once with each combination of m and time. At the end, sum should be the sum of all these equations. However, I don't know what kappa and z1 are, so my script may need some tweaking.
Another way to do this:
output <- expand.grid(time = 1:200, m =1:1000)
output[,"sum"] <- with(output, sum(1/(1+2*m)^2)*exp( (-kappa*(1+2*m)^2 * pi^2 * time)/(z1^2)))

Resources