i am trying to generate subsequent entries for Sn with this relation Sn=Sn-1 +Xn
my Xn is (1x2) matrix
Sn is (1x2) matrix
yn is a scalar
y=numeric()
s=matrix(0,nrow=1,ncol=2)
mu=(1,0)
cov= matrix(c(1,0,0,1),2,2)
invcov=solve(cov)
s[1,]=c(0,0)
for (i in 2:10){
x=mvrnorm(1,mu,cov)
s[i,]=s[i-1,]+x
y[i]=t(s[i,])%*%invcov%*%s[i,]
}
i tried the code above and i keep getting this error message "Error in [<-(*tmp*, i, , value = c(0.719138301056081, -1.96625516396033 : subscript out of bounds"
can i get any ideas on how to correct the error?
You can't append to a matrix like that:
m <- matrix(0, nrow=1, ncol=2)
m[2,] <- c(1, 1)
#Error in `[<-`(`*tmp*`, 2, , value = c(1, 1)) : subscript out of bounds
You could use rbind, but it's better to pre-allocate (you know the final size of the matrix):
m <- matrix(0, nrow=2, ncol=2)
m[2,] <- c(1, 1)
# [,1] [,2]
#[1,] 0 0
#[2,] 1 1
That way you also avoid the Second Circle of the R-Inferno.
Related
I'd like to generate set of list object.
To start, I have a 2*2 matrix from which I should get a list of output.
The list contains: a projection matrix, an asymptotic dynamic, a transient dynamic and a matrix of elasticity: hence 4 objects. I can have all of them from the function projection.
My difficulty is that:
In task 1, I'd like to vary one of the elements (the third called gamma) of the starting matrix and then get a list of as many output as possible.
What I did shows only the first element of the list for each iteration.
#Creating function projection matrix
projection<- function(sigma1,sigma2,gama,phi){
A <- matrix(c(sigma1*(1-gama),phi,sigma1*gama, sigma2),
byrow = T, ncol = 2)
if(sigma1>1|sigma1<0){stop("sigma1 must be bounded in 0 and 1")}
if(gama>1|gama<0){stop("gama must be bounded in 0 and 1")}
if(phi<0){stop("phi must be greater or equal to 0")}
library(popbio)
e.a <- eigen.analysis(A)
as <- e.a$lambda1
tr <- -log(as)
Dynamic <- list(projection.matrix = A, assymtotic.dynamic=as,
transient.dynamic=tr, Elasticity=e.a$elasticities)
return(Dynamic)
}
#Try with B
B <- projection(0.5,0.9,0.1,1.5)
#Task 1
Task1 <- function(Gama){
n <- length(as.vector(Gama))
g <- list()
for (i in 1:n){g[i]<-projection(sigma1 = 0.5,sigma2 = 0.9,
gama = Gama[i],phi = 1.5)}
return(g)
}
G <- seq(from=0, to=1, by= 0.1)
Task1(G)
There's a fairly easy fix. Instead of using [<- for the assignment of the indexed projection-object use instead the [[<- function and don't forget to assign the result to an object name so you can inspect and use it. Otherwise there will only be material printed at the console but the result will be in the (temporary) environment of the function which will get garbage-collected.
Task1 <- function(Gama){
n <- length(as.vector(Gama))
g <- list()
for (i in 1:n){g[[i]]<-projection(sigma1 = 0.5,sigma2 = 0.9,
gama = Gama[i],phi = 1.5)}
return(g)
}
G <- seq(from=0, to=1, by= 0.1)
resG <- Task1(G)
resG[1]
#--- result is a list of list.
[[1]]
[[1]]$projection.matrix
[,1] [,2]
[1,] 0.5 1.5
[2,] 0.0 0.9
[[1]]$assymtotic.dynamic
[1] 0.9
[[1]]$transient.dynamic
[1] 0.1053605
[[1]]$Elasticity
[,1] [,2]
[1,] 0 0
[2,] 0 1
I typically use Rsolnp for optimization but I am having trouble figuring out how to ask R to find values to fill a matrix (instead of a vector). Is that possible with Rsolnp or any other optimizer?
Here is a simplified example that is not working:
library(Rsolnp)
a<-matrix(rnorm(9), ncol=3)
b<-matrix(rnorm(9), ncol=3)
f1<-function(H) {
return(sum(H*a))
}
f2<-function(H) {
return(sum(H*b))
}
lH<-matrix(rep(0, 9), ncol=3)
uH<-matrix(rep(1, 9), ncol=3)
pars<-uH
target<-1.2
sol <- gosolnp(pars, fixed=NULL, fun=f1, eqfun=f2, eqB=target, LB=lH, UB=uH, distr=uH, n.restarts=10, n.sim=20000, cluster= NULL)
As you can see from the output, Rsolnp seems to be confused by the request:
> sol
$values
[1] 1e+10
$convergence
[1] 0
$pars
[1] NA NA NA NA NA NA NA NA NA
$start.pars
[1] 0.90042133 0.33262541 0.94586530 0.02083822 0.99953060 0.10720068 0.14302770 0.67162637 0.25463806
$rseed
[1] 1487866229
It seems that gosolnp() does not work with matrices. I went through the function in debugging mode and there is a call of solnp() that fails with the message:
Error in pb/cbind(vscale[(neq + 2):(neq + mm + 1)], vscale[(neq + 2):(neq + :
non-conformable arrays
But since a matrix is just a vector with the dimension attribute set, you can always reformulate your problem in terms of vectors. In your case, this is very easy, because you never do something that actually requires a matrix (like, for instance, a matrix product). Just omitting matrix() everywhere works fine.
But I assume that this is just a property of your simplified problem and your actual problem indeed needs to be expressed in terms of matrices. You could get around the problem by converting your vectors into matrices only inside the functions f1() and f2() as follows:
f1 <- function(H) {
return(sum(matrix(H, ncol = 3) * a))
}
f2 <- function(H) {
return(sum(matrix(H, ncol = 3) * b))
}
You can then define a and b as matrices as before, but lH and uH must be vectors:
a <- matrix(rnorm(9), ncol=3)
b <- matrix(rnorm(9), ncol=3)
lH <- rep(0, 9)
uH <- rep(1, 9)
pars <- uH
target <- 1.2
And now you can call gosolnp():
sol <- gosolnp(pars, fixed = NULL, fun = f1, eqfun = f2,
eqB = target, LB = lH, UB = uH, distr = uH,
n.restarts = 10, n.sim = 20000, cluster = NULL)
sol$pars
## [1] 3.917819e-08 9.999997e-01 4.748336e-07 1.000000e+00 5.255060e-09 5.114680e-10
## [7] 4.899963e-01 1.000000e+00 9.260947e-08
When calling diag<-, you can pass a slice of the matrix and get the proper behavior, as long as you don't specify drop=FALSE.
> X <- matrix(0, 3, 3)
> diag(X[-1,]) <- c(1,2)
> X
[,1] [,2] [,3]
[1,] 0 0 0
[2,] 1 0 0
[3,] 0 2 0
Specifying drop=false is a different story
> diag(X[-1,,drop=FALSE]) <- c(3,4)
Error in diag(X[-1, , drop = FALSE]) <- c(3, 4) :
incorrect number of subscripts
Note:
> identical(X[-1,], X[-1,,drop=FALSE])
[1] TRUE
As noted by MrFlick, assignment to a slice when the drop argument results in the same error:
X[1,] <- 1
X[1,,drop=TRUE] <- 2
Error in X[1, , drop = TRUE] <- 2 : incorrect number of subscripts
Why is this happening?
According to the ?"[<-" help page, drop= "only works for extracting elements, not for the replacement" Thus you are not allowed to use a <- with drop which is basically what diag() is doing. As in my comment above, something like X[,,drop=TRUE] <- 1:9 is not allowed either. Too bad the error message isn't a bit more specific.
I am trying to multiply matrices. The values within the matrices represent probabilities that are different for each cycle. Therefore, I use loop for to update the values within the matrix. At the beginning it works fine, but then I get the feedback: subscript out of boundaries. The error message is showing my next values [4,] 210, 323, 467. Why are they not displayed at the bottom?
> initial_patient_distribtion <- c (1000,0,0)
> aaa <- c(1,0.7,0.6,0.5,0.4)
> bbb <- c(1, 0.2,0.3, 0.4, 0.5)
> ccc <- c(1, 0.1,0.1,0.1,0.1)
>
> cycle_patient_distribution_dasa_no2nd[1,] <-initial_patient_distribtion
> for (i in 2:length(aaa)){
+ trans_matrix_dasa_no2nd <- matrix (,nrow=3,ncol=3)
+ trans_matrix_dasa_no2nd[1,] <- c(aaa[i],bbb[i],ccc[i])
+ trans_matrix_dasa_no2nd[2,] <- c(0,0.5,0.5)
+ trans_matrix_dasa_no2nd[3,] <- c(0,0,1)
+
+ cycle_patient_distribution_dasa_no2nd[i,] <- cycle_patient_distribution_dasa_no2nd[i-1,]%*%(trans_matrix_dasa_no2nd)}
Error in `[<-`(`*tmp*`, i, , value = c(210, 323, 467)) :
subscript out of bounds
>
> cycle_patient_distribution_dasa_no2nd
[,1] [,2] [,3]
[1,] 1000 0 0
[2,] 700 200 100
[3,] 420 310 270
Your for loop goes to length(aaa) (5) and tries to access cycle_patient_distribution_dasa_no2nd[i,] when i==5. However, you'll see that cycle_patient_distribution_dasa_no2nd[5,] throws an error because the dimensions of that matrix are 3x3.
If your code does what you want otherwise, then you need to either change the ending index in your for loop to 3, or modify the dimensions of your matrix:
trans_matrix_dasa_no2nd <- matrix (,nrow=length(aaa),ncol=3)
I have 2 matrices.
The first one:
[1,2,3]
and the second one:
[3,1,2
2,1,3
3,2,1]
I'm looking for a way to multiply them.
The result is supposed to be: [11, 13, 10]
In R, mat1%*%mat2 don't work.
You need the transpose of the second matrix to get the result you wanted:
> v1 <- c(1,2,3)
> v2 <- matrix(c(3,1,2,2,1,3,3,2,1), ncol = 3, byrow = TRUE)
> v1 %*% t(v2)
[,1] [,2] [,3]
[1,] 11 13 10
Or potentially quicker (see ?crossprod) if the real problem is larger:
> tcrossprod(v1, v2)
[,1] [,2] [,3]
[1,] 11 13 10
mat1%%mat2 Actuall y works , this gives [ 16 9 11 ]
but you want mat1 %% t(mat2). This means transpose of second matrix, then u can get [11 13 10 ]
Rcode:
mat1 = matrix(c(1,2,3),nrow=1,ncol=3,byrow=TRUE)
mat2 = matrix(c(3,1,2,2,1,3,3,2,1), nrow=3,ncol=3,byrow=TRUE)
print(mat1)
print(mat2 )
#matrix Multiplication
print(mat1 %*% mat2 )
# matrix multiply with second matrix with transpose
# Note of using function t()
print(mat1 %*% t(mat2 ))
It's difficult to say what the best answer here is because the notation in the question isn't in R, it's in matlab. It's hard to tell if the questioner wants to multiple a vector, 1 row matrix, or 1 column matrix given the mixed notation.
An alternate answer to this question is simply switch the order of the multiplication.
v1 <- c(1,2,3)
v2 <- matrix(c(3,1,2,2,1,3,3,2,1), ncol = 3, byrow = TRUE)
v2 %*% v1
This yields an answer that's a single column rather than a single row matrix.
try this one
x<-c()
y<-c()
for(i in 1:9)
{
x[i]<-as.integer(readline("Enter number for 1st matrix"))
}
for(i in 1:9)
{
y[i]<-as.integer(readline("Enter number for 2nd matrix"))
}
M1 <- matrix(x, nrow=3,ncol = 3, byrow=TRUE)
M2 <- matrix(y, nrow=3,ncol = 3, byrow=TRUE)
print(M1%*%M2)