Is there any way to calculate the matrix of cofactors in R directly?
(Without multiplying it by determinant!)
http://en.wikipedia.org/wiki/Minor_(linear_algebra)#Matrix_of_cofactors
Build your own function:
library(functional)
M<-matrix(1:9,3,3)
getCofactor = function(M, i, j)
{
stopifnot(length(unique(dim(M)))==1)
stopifnot(all(c(i,j)<=dim(M)))
det(M[-i,-j])*(-1)^(i+j)
}
grid = expand.grid(1:dim(M)[1], 1:dim(M)[2])
matrix(mapply(Curry(getCofactor, M=M), grid$Var1, grid$Var2), nrow=dim(M)[1])
You can write a function that gives you the whole matrix of cofactors with one click.
getCofactors <- function(M) {
stopifnot(length(unique(dim(M)))==1) # Check if Matrix = Square
cf <- M # creating a Matrix that has the same Dimensions as M
for(i in 1:dim(M)[1]){
for(j in 1:dim(M)[2]){
cf[i,j] <- (det(M[-i,-j])*(-1)^(i+j)) # overwriting the Values of cf Matrix with cofactors
}
}
return(cf) # output of cofactors matrix
}
If you Want you can save your function and load it on demand:
dump("getCofactors", file="getCofactors.R")
source("getCofactors.R")
Related
How do I populate a 10X10 empty matrix called mat.horiz, with values 1 to 100 by row (i.e. filling in values across columns, in descending rows), using two for() loops?
New to loops and am barely grasping the structure of them. Any help and explanation would be much appreciated:)
If you really want to use for loops, you can try the code below
out <- matrix(NA,10,10)
for (i in 1:10) {
for (j in 1:10) {
out[i,j] <- j + (i-1)*10
}
}
or
out <- matrix(NA,10,10)
k <- 0
for (i in 1:10) {
for (j in 1:10) {
k <- k + 1
out[i,j] <- k
}
}
A simpler way is using
out <- matrix(1:100,10,10,byrow = TRUE)
I want to use the matlab syntax below in term of R code, actually X is a nxm matrix:
Hs(i,j)=norm(X(i,:)-X(j,:))^2;
Hs(j,i)=Hs(i,j);
Hs=exp(-Hs/3);
Here is my R code:
Hs[i,j]=sqrt(sum((X[i,]- X[j,])^2))
Hs[i,j]=Hs[j,i]
Hs=exp(-Hs/3)
But the problem the result output was matrix 3x3 with all element =1. Please help.
Here the answer:
#Euclidean matrix
euc.dist <- function(p, q) {
ed<-sqrt(sum((p - q)^2))
return((ed))
}
#Gaussian kernel nxn matrix
get.gramm.nn <- function(X) {
n <- dim(X)[1]
Gramm<- matrix(0, n, n) #initializes Gramm array #i=index for rows
#j=index for columns Gramm<-as.matrix(Gramm) # Gramm matrix
for (i in 1:n) {
for (j in 1:n) {
Gramm[i, j] <- euc.dist(X[i,], X[j,])
}
}
Gramm<- exp(-(Gramm)^2)
return(Gramm)
}
I am trying to implement a nested summation in R. The for loop implementation is:
sum = 0
for(i in 1:n){
for(j in 1:n){
for(k in 1:n){
sum = sum + w[i,j]*w[j,k]
}
}
}
where w is a symmetric square matrix and n is the number of rows (or columns).
Please see the formula I am trying to implement. (SO did not allow me to write Latex nor add the image here.)
The nested for loops above takes forever. How do I implement this efficiently the R way?
Try this:
Sum2 <- sum(w %*% w)
all.equal(Sum, Sum2)
## [1] TRUE
Note
We used for comparison:
# input
set.seed(123)
n <- 5
w <- matrix(rnorm(n^2), n)
# from question
Sum = 0
for(i in 1:n){
for(j in 1:n){
for(k in 1:n){
Sum = Sum + w[i,j]*w[j,k]
}
}
}
Here are my R code. Could you please give me some advice so that can accelerate the computational speed :)
First, the function myfun()generates a complex number.
Second, I compute the elements of matrix M using myfun().
myfun<-function(a,b,nq,ul,uk)
{
m<-seq(1,(nq/2)+1,length=(nq/2)+1);
k<-m;
D<-matrix(NA,nrow = length(k),ncol = length(k));
for(i in 1:length(k)) # row
for(j in 1:length(m)) # column
{
D[i,j]<-(2/nq)*cos(((j-1)*(i-1)*pi)/(nq*0.5))
}
D[,1]<-D[,1]*0.5;
D[,ncol(D)]<-D[,ncol(D)]*0.5;
# compute the vector v
vseq<-seq(2,nq-2,by=2);
vr<-2/(1-vseq^2);
vr<-c(1,vr,1/(1-nq*nq));
v<-matrix(vr,ncol=1); # v is a N by 1 matrix
# compute the vector w, length(w)=nq/2+1
h<-function(x,ul,uk)
{
((b-a)/2)*(exp((b-a)/2*x+(a+b)/2)+1)^(1i*uk)*cos(((b-a)/2*x+(a+b)/2-a)*ul)
}
w<-matrix(rep(NA,length(v)),ncol=1);
for(i in 1:length(w))
{
w[i]<-h((cos((i-1)*pi/nq)),ul,uk)+h((-cos((i-1)*pi/nq)),ul,uk)
}
res<-t(t(D)%*%v)%*%w; # each element of matrix M
return(res)
}
Next, compute each element of matrix M. The N-th column and N-th row are zeros.
matrix.M<-matrix(0,ncol = N,nrow = N);
for(i in 1:N-1)
for(j in 1:N-1)
{
matrix.M[i,j]<-myfun(a,b,nq,i-1,j-1)
}
We can set parameters as
a<--173.2;
b<-78;
alpha<-0.24;
Dt<-0.1;
M<-1000;
N<-150;
u<-seq(1,150,by=1)*pi/(b-a);
nq<-3000;
I appreciate your help!
Here are some suggestions for speeding the function up. I use three "tricks":
Vectorize as many functions as possible
Use the outer function instead of a double loop
Use the hidden gem crossprod for the final matrix products
myfun<-function(a,b,nq,ul,uk) {
m<-seq(1,(nq/2)+1,length=(nq/2)+1);
k<-m;
## Use outer to compute the elements of the matrix
D <- outer(1:length(k), 1:length(m), function(i, j) {(2/nq)*cos(((j-1)*(i-1)*pi)/(nq*0.5))} )
D[,1]<-D[,1]*0.5;
D[,ncol(D)]<-D[,ncol(D)]*0.5;
# compute the vector v
vseq<-seq(2,nq-2,by=2);
vr<-2/(1-vseq^2);
vr<-c(1,vr,1/(1-nq*nq));
v<-matrix(vr,ncol=1); # v is a N by 1 matrix
h<-function(x,ul,uk) {
((b-a)/2)*(exp((b-a)/2*x+(a+b)/2)+1)^(1i*uk)*cos(((b-a)/2*x+(a+b)/2-a)*ul)
}
## Compute the full w vector in one go
vect <- seq_along(v)-1
w <- h((cos(vect*pi/nq)),ul,uk) + h((-cos(vect*pi/nq)),ul,uk)
## Compute the cross products.
res <- crossprod(crossprod(D, v), w)
return(res)
}
I think this should save around 80% of the time compared to the original function. The time hog was the initial computation of D. Hope this helps.
I have the following code in R:
z <- scale(x) / sqrt(n-1) # standardized matrix x such that z'z=correlation matrix
R <- t(z) %*% z # correlation matrix
I <- diag(py - 1) # identity matrix(py defined before)
df <- rep(0, length(k)) # k=seq(0,5,0.001)
for (i in seq(0,5,0.001)) {
H <- z %*% solve(R+(i*I)) %*% t(z)
tr <- sum(diag(H))
df <- c(df,tr) ## problem here
}
The last line in the code is not good, as what I want is a vector (df) that reads each number from tr for each i, so that df returns a vector containing all tr.
Any help is appreciated.
Thanks
Separate the points that you want to solve at from the loop index.
solve_points <- seq(0,5,0.001)
for(i in seq_along(solve_points))
{
H=z%*%solve(R+(solve_points*I))%*%t(z)
tr=sum(diag(H))
df[i] <- tr
You want to fill in the vector df, not concatenate it all the time. That will slow R down a lot as it has to copy the object each iteration of the loop.
I think you probably want something like this:
for (i in seq_along(k)) { ## loop over 1:length(k)
H <- z %*% solve(R+(k[i]*I)) %*% t(z) ## use i to index into k
tr <- sum(diag(H))
df[i] <- tr ## add `tr` to the ith element of df
}
but a reproducible example would have helped. For example, you might not need to index k, depends on what your code is really doing and you don;t provide all the objects to check.