R eqivalent to Matlab cell2mat function? - r

I am not very experienced with R or Matlab, and I am trying to convert a Matlab code to R. The problem is, I am not exactly sure what the code does. Here is the matlab line I am having trouble with:
Wi = cell2mat(accumarray(s_group,s_u,[],#(x){repmat(sqrt(sum(x.*x)+eps),length(x),1)}));
I cannot find an R function that does the same sort of thing as the cell2mat in matlab.
When I run the code with my example data, the matlab gives me an array of length 86, which is the same length as the s_group and s_u variables.
However, when I use the same data with this R code:
Wi<-accumarray(s_group,s_u,sz=c(nrow(s_group),ncol(s_group)),func=function(x) matrix(sqrt(x*x),length(x),1))
it gives me the error
Error in accumarray(s_group, s_u, sz = c(length(s_group), 1), func = function(x) matrix(sqrt(x * :
Argument 'sz' does not fit with 'subs'.
I also tried it without the size specified:
Wi<-accumarray(s_group,s_u,func=function(x) matrix(sqrt(x*x),length(x),1))
and this gave me an array of length 21 with the error:
In A[i] <- func(val[subs == i]) :
number of items to replace is not a multiple of replacement length
Here is the original for-loop version from Matlab:
group_set = unique(group);
group_num = length(group_set);
Wi = zeros(n_XVar, 1);
for c = 1:group_num
idx = find(group==group_set(c));
Wc = u(idx,:);
di = sqrt(sum(sum(Wc.*Wc))+eps);
Wi(idx) = di;
end
Does anyone know what I can do to put this into R without using a for-loop?
Many thanks!

It seems the cell2mat function in Matlab turns a matrix of matrixes into a single matrix. A matrix of matrixes isn't exactly a common data type in R. But you can make one with
a<-matrix(list(), 2,2)
a[[1,1]]<-matrix(1, nrow=1)
a[[1,2]]<-matrix(2:4, nrow=1)
a[[2,1]]<-matrix(c(5,9), nrow=2)
a[[2,2]]<-matrix(c(6:8, 10:12), nrow=2, byrow=T)
(like the example on the MatLab help page for cel2mat). An R translation of that code might be
cell2mat<-function(m)
do.call(rbind, apply(m, 1, function(x) do.call(cbind,x)))
Which we can test wtih
cell2mat(a)
# [,1] [,2] [,3] [,4]
# [1,] 1 2 3 4
# [2,] 5 6 7 8
# [3,] 9 10 11 12
This is probably not the most efficient translation but it's probably the simplest.

Related

Two errors in writing R code of QR decomposition using Gram-Schmidtand method and want to know why it went wrong

I write code manually of QR decomposition using Gram-Schmidt orthogonalization:
A<-cbind(c(2,-2,18),c(2,1,0),c(1,2,0),c(2,3,4))
gsm<-function(X){
m<-ncol(X)
n<-nrow(X)
# initialize Q and R
q<-matrix(0,m,n)
r<-matrix(0,n,n)
v<-matrix(0,m,n)
# initialize V
v[,1]<-X[,1]
q[,1]<-v[,1]/sqrt(sum(v[,1]^2))
r[1,1]<-t(X[,1])%*%q[,1]
for (i in 2:n){
dv<-0
for (j in 1:(i-1)) {
r[j,i]<-t(X[,i])%*%q[,j]
dv<-dv+r[j,i]*q[,j]
}
v[,i]<-X[,i]-dv
q[,i]<-v[,i]/sqrt(t(v[,i])%*%v[,i])
r[i,i]<-t(X[,i])%*%q[,i]
}
qrreport<-list("Q"=q,"R"=r)
return(qrreport)
}
gsm(A)
However, the code doesn't work and gives me the error:
Error in v[, 1] <- X[, 1] : number of items to replace is not a multiple of replacement length
And when I replace A with a 3*3 matrix: A<-cbind(c(2,-2,18),c(2,1,0),c(1,2,0)) and operate the function again, R throws a new error to me as:
Recycling array of length 1 in vector-array arithmetic is deprecated.
Use c() or as.vector() instead.
Recycling array of length 1 in vector-array arithmetic is deprecated.
Use c() or as.vector() instead.
$ Q
[,1] [,2] [,3]
[1,] 0.1097643 0.89011215 -0.4423259
[2,] -0.1097643 0.45314800 0.8846517
[3,] 0.9878783 -0.04855157 0.1474420
$R
[,1] [,2] [,3]
[1,] 18.22087 0.1097643 -0.1097643
[2,] 0.00000 2.2333723 1.7964082
[3,] 0.00000 0.0000000 1.3269776
I am very confused where I make mistakes and hope someone could help me debug.
Your A matrix has 3 rows and 4 columns, so in gsm() m is 4 and n is 3. That means v has 4 rows and 3 columns, whereas X, which is really A, only has 3 rows. When v[, 1] <- X[, 1] tries to put the 1st column of X into the first
column of A, you get the error message you saw.
To debug things like this in RStudio, set a breakpoint on the line v[, 1] <- X[, 1] that caused the error, and look at the different items in the expression before executing it. If you're not using RStudio, you can still set a breakpoint there using the setBreakpoint function, but it's a lot more work.

Coerce a string to be an input into matrix function within a function

EDIT: For anyone interested, I completed my little project here and it can be seen at this link http://fdrennan.net/pages/myCurve.html
Scroll down to "I think it's been generalized decently" to see the curve_fitter function. If you find it useful, steal it and I don't need credit. I still have ncol as an input but it isn't required anymore. I just didn't delete it.
I am writing a script that will do some least squares stuff for me. I'll be using it to fit curves but want to generalize it. I want to be able to write in "x, x^2" in a function and have it pasted into a matrix function and read. Here is what I am talking about.
expressionInput <- function(func = "A written function", x = "someData",
nCol = "ncol") {
# Should I coerce the sting to something in order to make...
func <- as.SOMETHING?(func)
# ...this line to be equivalent to ...
A <- matrix(c(rep(1, length(x)), func), ncol = nCol)
# .... this line
# A <- matrix(c(rep(1, length(x)), x, x^2), ncol = 3)
A
}
expressionInput(func = "x, x^2", x = 1:10, nCol = 3)
Returns 10 x 3 matrix with 1's in one column, x in second, and squared values in third column.
The link below will show a few different functions for curve fitting. The idea behind this post is to be able to write in "x + x^2" or "x + sin(x)" or "e^x" etc., and return the coefficients for curve.
http://fdrennan.net/pages/myCurve.html
I think you are looking for something like this
f <- function(expr="", x=NULL, nCol=3) {
expr <- unlist(strsplit(expr,","))
ex <- rep("rep(1,length(x))", nCol)
ex[1:length(expr)] <- expr
sapply(1:length(ex), function(i) eval(parse(text=ex[i])))
}
f("x, x^2", 1:10, 3)
[,1] [,2] [,3]
[1,] 1 1 1
[2,] 2 4 1
[3,] 3 9 1
[4,] 4 16 1
[5,] 5 25 1
[6,] 6 36 1
[7,] 7 49 1
[8,] 8 64 1
[9,] 9 81 1
[10,] 10 100 1
Note that, in your example, you separate the expressions to evaluate using a comma (,). Accordingly, I have used a comma to split the string into expressions. If you try passing expressions, which themselves contain commas this will fail. So, either restrict to using simple expressions without commas. Or if this is not possible then use a different character to separate the expressions (and escape it, if you need that character to be evaluated).
However, I would also reiterate the warnings in the comments to your question that depending on what you are trying to achieve, there are likely better ways to do it.

Double loop in R with a matrix

I know the error that I commit, but I cannot find any solution. I'm programming a double loop for simulating with the Monte Carlo method.
set.seed(-1256,normal.kind="Box-Muller")
A <- matrix(Nsimul,85)
for (k in 1:Nsimul) {
r=c()
r[1]=r0_CIR
S=c()
S[1]=I0
A[,1]=r0_CIR
for(j in 1:NumPassi){
epsilon=rnorm(2,0,1)
r[j+1]= r[j]+alphaStar*(gammaStar-r[j])*Deltat + rho*sqrt(r[j])*epsilon[1]*sqrt(Deltat)
if (r[j+1]<0) r[j+1]=abs(r[j+1])
epsilon_S=epsilon[1]+sqrt(1-corr^2)*epsilon[2]
S[j+1]=S[j]*exp((r[j]-sigma^2/2-div)*Deltat+sigma*epsilon_S*sqrt(Deltat))
A[k,j+1]=r[j+1]
}
}
when I try to run the code I have this error
Error in `[<-`(`*tmp*`, , j + 1, value = 0.0102279735166489) : subscript out of bounds
I don't understand which value is out of bounds.
While you may incrementally grow vectors by calling indeces that don't exist (not a great practice but I digress), for example
S<-c()
S[1]<-1
S
#[1] 1
You may not do so in the method you are trying to with the matrix A in your example.
Here is an example matrix I made
A<-matrix(1:10, nrow=5)
# [,1] [,2]
#[1,] 1 6
#[2,] 2 7
#[3,] 3 8
#[4,] 4 9
#[5,] 5 10
and if I try
A[1,3]<-1
I get
#Error in A[1, 3] <- 2 : subscript out of bounds
While you have many things undefined in your question, such as A, Numsimul, Numpassi, so I can't know for sure what's going on, but the final line of the second for loop is most likely the issue. If the value for j becomes larger than the number of columns in your matrix A, then you will have an error thrown on you.
You must ensure that the column exists first before you begin setting it in the second for loop

Sum and product over interval in R

I am trying to implement the following simple formulas in R:
Formula 1:
I have no idea how to implement in R the product operator when the limits of the interval are very large (e.g. value of the upper limit = 10,000 instead of 5)
Formula 2
Example input for second formula (in reality, the dimension of the interval S is much much bigger)
S = list(c(1,0,0), c(0,1,0), c(0,0,1))
X = c(1,2,3)
Any help would be appreciated!
For the first, take the log:
i *log(1+x)
For the second formula: (not clear what is the expected output)
ss<-matrix(unlist(S), ncol = 3, byrow = TRUE)
X<-as.matrix(X)
crossprod(crossprod(X,ss),t(X))
[,1] [,2] [,3]
[1,] 1 2 3
[2,] 2 4 6
[3,] 3 6 9
Maybe more compactly:
First formula:
function(n, x) exp(sum(seq_len(n)*log(1+x)))
Second formula:
function(X, S) rowSums(sapply(S, function(y) sum(X*y)*X ))
For the first formula it has been mentioned that it is better to do this on the log scale, if your true values of x are near 0 then the log1p function may be of help.
In general for these types of problems you can use lapply or sapply to compute the pieces that need to be multiplied or summed (or whatever), then use sum or prod to sum, multiply. If you want to collapse/combine the values with an operator that does not have a nice function like sum or prod then use the Reduce function.
S = list c((1,0,0), c(0,1,0), c(0,0,1))
X = c(1,2,3)
lapply( lapply(S, function(x) X %*% x %*% t(X) ) , sum)
[[1]]
[1] 6
[[2]]
[1] 12
[[3]]
[1] 18

Matrix power in R

Trying to compute the power of a matrix in R, I found that package expm implements the operator %^%.
So x %^% k computes the k-th power of a matrix.
> A<-matrix(c(1,3,0,2,8,4,1,1,1),nrow=3)
> A %^% 5
[,1] [,2] [,3]
[1,] 6469 18038 2929
[2,] 21837 60902 9889
[3,] 10440 29116 4729
but, to my surprise:
> A
[,1] [,2] [,3]
[1,] 691 1926 312
[2,] 2331 6502 1056
[3,] 1116 3108 505
somehow the initial matrix A has changed to A %^% 4 !!!
How do you perform the matrix power operation?
I have fixed that bug in the R-forge sources (of "expm" package),
svn rev. 53. --> expm R-forge page
For some reason the web page still shows rev.52, so the following may not yet
solve your problem (but should within 24 hours):
install.packages("expm", repos="http://R-Forge.R-project.org")
Otherwise, get the svn version directly, and install yourself:
svn checkout svn://svn.r-forge.r-project.org/svnroot/expm
Thanks to "gd047" who alerted me to the problem by e-mail.
Note that R-forge also has its own bug tracking facilities.
Martint
This is not a proper answer, but may be a good place to have this discussion and understand the inner workings of R. This sort of bug has crept up before in another package I was using.
First, note that simply assigning the matrix to a new variable first does not help:
> A <- B <-matrix(c(1,3,0,2,8,4,1,1,1),nrow=3)
> r1 <- A %^% 5
> A
[,1] [,2] [,3]
[1,] 691 1926 312
[2,] 2331 6502 1056
[3,] 1116 3108 505
> B
[,1] [,2] [,3]
[1,] 691 1926 312
[2,] 2331 6502 1056
[3,] 1116 3108 505
My guess is that R is trying to be smart passing by reference instead of values. To actually get this to work you need to do something to differentiate A from B:
`%m%` <- function(x, k) {
tmp <- x*1
res <- tmp%^%k
res
}
> B <-matrix(c(1,3,0,2,8,4,1,1,1),nrow=3)
> r2 <- B %m% 5
> B
[,1] [,2] [,3]
[1,] 1 2 1
[2,] 3 8 1
[3,] 0 4 1
What is the explicit way of doing this?
Finally, in the C code for the package, there is this comment:
NB: x will be altered! The caller must make a copy if needed
But I don't understand why R lets C/Fortran code have side effects in the global environment.
An inefficient version (since it's more efficient to first diagonalize your matrix) in base without much effort is:
pow = function(x, n) Reduce(`%*%`, replicate(n, x, simplify = FALSE))
I know this question is specifically about an old bug in expm, but it's one of the first results for "matrix power R" at the moment, so hopefully this little shorthand can be useful for someone else who ends up here just looking for a quick way to run matrix powers without installing any packages.
Although the source-code is not visible in the package since it is packed in a .dll file, I believe the algorithm used by the package is the fast exponentiation algorithm, which you can study by looking at the function called matpowfast instead.
You need two variables :
result, in order to store the output,
mat, as an intermediate variable.
To compute A^6, since 6 = 110 (binary writing), in the end, result = A^6 and mat = A^4. This is the same for A^5.
You could easily check if mat = A^8 when you try to compute A^n for any 8<n<16. If so, you have your explanation.
The package function uses the initial variable A as the intermediate variable mat.
Very quick solution without using any package is using recursivity:
if your matrix is a
powA = function(n)
{
if (n==1) return (a)
if (n==2) return (a%*%a)
if (n>2) return ( a%*%powA(n-1))
}
HTH
You can simply use the Eigen values and Eigen vectors to compute the exponential of a matrix ;
# for a given matrix, A of power n
eig_vectors <- eigen(A)$vectors
eig_values <- eigen(A)$values
eig_vectors %*% diag(eig_values)^n %*% solve(eig_vectors)
Alternatively an improved answer from #MichaelChirico. The exponent 0 of a matrix will return its identity matrix instead of NULL.
pow = function(x, n) {
if (n == 0) {
I <- diag(length(diag(x)))
return(I)
}
Reduce(`%*%`, replicate(n, x, simplify = FALSE))
}
A^5 = (A^4)*A
I suppose the library mutates the original variable, A, so that the each step involves multiplying the result-up-till-then with the original matrix, A. The result you get back seem fine, just assign them to a new variable.

Resources