Double loop in R with a matrix - r

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

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.

get an element from a subset of a matrix in Rarmadillo

I have a large-ish matrix. I'm trying to sample from it with dynamically changing weights. As it's forced to use loops in R, I'm trying to implement it in Rcpp so it has the chance of running a bit faster. After a bit of experimenting, I think I've figured out how to grab an index at random with the correct weights.
The trick is that I'm only sampling from a subset of columns at any given time (this can change to rows if it's more efficient in C - the matrix is actually symmetric). My indices are only defined for this subset of columns. In R, I'd do something along the lines of
large_matrix[, columns_of_interest][index]
and this works fine. How would I do the equivalent using Rcpp/Armadillo? My guess of
cppFunction("arma::vec element_from_subset(arma::mat D, arma::uvec i, arma::uvec columns) {
# arma::mat D_subset = D.cols(columns);
return D.cols(columns).elem(i);
}", depends = "RcppArmadillo")
fails to compile (and .at instead of .elem doesn't work either, nor does the standard R trick of surrounding things in paranthesis.
This does work, but is what I'm trying to avoid:
cppFunction("arma::vec element_from_subset(arma::mat D, arma::uvec i, arma::uvec columns) {
arma::mat D_subset = D.cols(columns);
return D_subset.elem(i);
}", depends = "RcppArmadillo")
Is there any way to accommplish this without needing to save D.cols(columns)?
Short answer: No.
But, the problem is phrased incorrectly. Think about what is happening here:
(M <- matrix(1:9, 3, 3))
#> [,1] [,2] [,3]
#> [1,] 1 4 7
#> [2,] 2 5 8
#> [3,] 3 6 9
columns_of_interest = 1:2
M[, columns_of_interest]
#> [,1] [,2]
#> [1,] 1 4
#> [2,] 2 5
#> [3,] 3 6
From here, if we have the index being 1, then we get:
index = 1
M[, columns_of_interest][index]
#> 1
So, in essence, what's really happening is an entry-wise subset of (i,j). Thus, you should just use:
Rcpp::cppFunction("double element_from_subset(arma::mat D, int i, int j) {
return D(i, j);
}", depends = "RcppArmadillo")
element_from_subset(M, 0, 0)
#> [1] 1
I say this based on the R and C++ code posted, e.g. R gives 1 value and C++ has a return type permitting only one value.
The code posted by OP is shown without the error. The initial error as compiled will indicate there is an issue using an Rcpp object inside of an arma class. If we correct the types, e.g. replacing Rcpp::IntegerVector with an arma appropriate type of either arma::ivec or arma::uvec, then compiling yields a more informative error message.
Corrected Code:
Rcpp::cppFunction("double element_from_subset(arma::mat D, int i, arma::uvec columns) {
return D.cols(columns).elem(i);
}", depends = "RcppArmadillo")
Error Message:
file6cf4cef8267.cpp:10:26: error: no member named 'elem' in 'arma::subview_elem2<double, arma::Mat<unsigned int>, arma::Mat<unsigned int> >'
return D.cols(columns).elem(i);
~~~~~~~~~~~~~~~ ^
1 error generated.
make: *** [file6cf4cef8267.o] Error 1
So, there is no way to subset a subview that was created by taking the a subset from an armadillo object.
You may want to read up on a few of the subsetting features of Armadillo. They are immensely helpful.
Rcpp Gallery: http://gallery.rcpp.org/articles/armadillo-subsetting
Guide to Converting R Code to Armadillo: http://thecoatlessprofessor.com/programming/common-operations-with-rcpparmadillo/
Armadillo specific documentation
Matrix subsets: http://arma.sourceforge.net/docs.html#submat
Individual entries: http://arma.sourceforge.net/docs.html#element_access
sub2ind(): http://arma.sourceforge.net/docs.html#sub2ind
ind2sub(): http://arma.sourceforge.net/docs.html#ind2sub
Disclaimer: Both the first and second links I've contributed to or written.

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.

Calculate a geometric progression

I'm using brute force right now..
x <- 1.03
Value <- c((1/x)^20,(1/x)^19,(1/x)^18,(1/x)^17,(1/x)^16,(1/x)^15,(1/x)^14,(1/x)^13,(1/x)^12,(1/x)^11,(1/x)^10,(1/x)^9,(1/x)^8,(1/x)^7,(1/x)^6,(1/x)^5,(1/x)^4,(1/x)^3,(1/x)^2,(1/x),1,x,x^2,x^3,x^4,x^5,x^6,x^7,x^8,x^9,x^10,x^11,x^12,x^13,x^14,x^15,x^16,x^17,x^18,x^19,x^20)
Value
but I would like to use an increment loop just like the for loop in java
for(integer I = 1; I<=20; I++)
^ is a vectorized function in R. That means you can simply use x^(-20:20).
Edit because this gets so many upvotes:
More precisely, both the base parameter and the exponent parameter are vectorized.
You can do this:
x <- 1:3
x^2
#[1] 1 4 9
and this:
2^x
#[1] 2 4 8
and even this:
x^x
#[1] 1 4 27
In the first two examples the length-one parameter gets recycled to match the length of the longer parameter. Thats why the following results in a warning:
y <- 1:2
x^y
#[1] 1 4 3
#Warning message:
# In x^y : longer object length is not a multiple of shorter object length
If you try something like that, you probably want what outer can give you:
outer(x, y, "^")
# [,1] [,2]
#[1,] 1 1
#[2,] 2 4
#[3,] 3 9
Roland already addressed the fact that you can do this vectorized, so I will focus on the loop part in cases where you are doing something more that is not vectorized.
A Java (and C, C++, etc.) style loop like you show is really just a while loop. Something that you would like to do as:
for(I=1, I<=20, I++) { ... }
is really just a different way to write:
I=1 # or better I <- 1
while( I <= 20 ) {
...
I <- I + 1
}
So you already have the tools to do that type of loop. However if you want to assign the results into a vector, matrix, array, list, etc. and each iteration is independent (does not rely on the previous computation) then it is usually easier, clearer, and overall better to use the lapply or sapply functions.

How can I make processing of matrices and vectors regular (as, e.g., in Matlab)

Suppose I have a function that takes an argument x of dimension 1 or 2. I'd like to do something like
x[1, i]
regardless of whether I got a vector or a matrix (or a table of one variable, or two).
For example:
x = 1:5
x[1,2] # this won't work...
Of course I can check to see which class was given as an argument, or force the argument to be a matrix, but I'd rather not do that. In Matlab, for example, vectors are matrices with all but one dimension of size 1 (and can be treated as either row or column, etc.). This makes code nice and regular.
Also, does anyone have an idea why in R vectors (or in general one dimensional objects) aren't special cases of matrices (or multidimensional objects)?
Thanks
In R, it is the other way round; matrices are vectors. The matrix-like behaviour comes from some extra attributes on top of the atomic vector part of the object.
To get the behaviour you want, you'd need to make the vector be a matrix, by setting dimensions on the vector using dim() or explicit coercion.
> vm <- 1:5
> dim(vm) <- c(1,5)
> vm
[,1] [,2] [,3] [,4] [,5]
[1,] 1 2 3 4 5
> class(vm)
[1] "matrix"
Next you'll need to maintain the dimensions when subsetting; by default R will drop empty dimensions, which in the case of vm above is the row dimension. You do that using drop = FALSE in the call to '['(). The behaviour by default is drop = TRUE:
> vm[, 2:4]
[1] 2 3 4
> vm[, 2:4, drop = FALSE]
[,1] [,2] [,3]
[1,] 2 3 4
You could add a class to your matrices and write methods for [ for that class where the argument drop is set to FALSE by default
class(vm) <- c("foo", class(vm))
`[.foo` <- function(x, i, j, ..., drop = FALSE) {
clx <- class(x)
class(x) <- clx[clx != "foo"]
x[i, j, ..., drop = drop]
}
which in use gives:
> vm[, 2:4]
[,1] [,2] [,3]
[1,] 2 3 4
i.e. maintains the empty dimension.
Making this fool-proof and pervasive will require a lot more effort but the above will get you started.

Resources