This is comp sci 101 stuff, but I couldn't find an answer applicable to R (or matlab).
I have a for loop that I want to initialize with a first guess (all zeros here, but maybe something else later), but I want to keep updating with each iteration. What I have below works, but it kind of clunky and embarrassing.
I would like to avoid the one iteration before the for loop. I could do it with an ifelse inside the loop, but that seems inefficient. Thanks!
alpha <- 0.3
beta <- 0.6
m <- 5 # elements in k
n <- 10 # iterations
k.prime <- v <- matrix(0, n, m)
k <- seq(from=0.04, to=0.2, length.out=m) # poss values for k
colnames(v) <- colnames(k.prime) <- round(k, digits=2)
# first loop for taking the first guess for v()
i <- 1
for (j in 1:m) {
temp.v <- log(k[j]^alpha - k) + beta*rep(0, times=m)
v[i, j] <- max(temp.v)
k.prime[i, j] <- k[which.max(temp.v)]
}
# remaining loops
for (i in 2:n) {
for (j in 1:m) {
temp.v <- log(k[j]^alpha - k) + beta*v[i-1, ]
v[i, j] <- max(temp.v)
k.prime[i, j] <- k[which.max(temp.v)]
}
}
v
k.prime
Init v[1,] with zeroes, delete the first loop and fix i index to i+1 elsewhere.
This should then look like this:
alpha<-0.3
beta<-0.6
m<-5 #elements in k
n<-10 #iterations
k.prime<-matrix(0,n,m);
v<-matrix(0,n+1,m);
k<-seq(from=0.04,to=0.2,length.out=m) #poss values for k
colnames(v)<-colnames(k.prime)<-round(k,digits=2)
v[1,]<-rep(0,m);
# remaining loops
for(i in 1:n){
for(j in 1:m){
temp.v<-log(k[j]^alpha-k)+beta*v[i,]
v[i+1,j]<- max(temp.v)
k.prime[i,j]<-k[which.max(temp.v)]
}
}
v[-1,]->v; #Cleanup of 0-row
v
k.prime
Just do :
for (i in 1:n) {
for (j in 1:m) {
if (i == 1)
temp.v <- log(k[j]^alpha - k) + beta*rep(0, times=m)
else
temp.v <- log(k[j]^alpha - k) + beta*v[i-1, ]
v[i, j] <- max(temp.v)
k.prime[i, j] <- k[which.max(temp.v)]
}
}
Related
I am currently trying to duplicate the diag() function in R to get a better understanding. Unfortunately, my solution is only useful for symmetric matrices.
diagnew <- function(x){
k <- c()
for(i in 1:nrow(x)){
k[i] <- x[i,i]
}
return(k)
}
I would be grateful for any tips that allow me to generalize my function.
The error comes from looping pass min(nrow, ncol).
diagnew <- function(x){
n <- min(nrow(x), ncol(x))
k <- vector(class(x[1,1]), n)
for(i in seq.int(n)){
k[i] <- x[i,i]
}
k
}
mat <- matrix(1:10, 5)
diag(mat)
diagnew(mat)
identical(diag(mat), diagnew(mat))
#[1] TRUE
Is there an efficient way to write the below code in R?
v is a matrix of length n x n.
k <- matrix(0, n, n-2)
for (i in seq(n)){
for (j in seq(n-2)) {
k[i,j] = v[i, j]
}
}
I'm currently working on an R program, where there is one part of this program that computes in a loop two values which are interdependant. Although since I have to do 100,000 iterations it takes so long time.
So I would like to substitute this for loop for an apply loop or some more efficient function, but I don't know how to do it. Could someone help me?
p <- c()
for(i in 1:n) {
if(i == 1) {
x <- b[i]
}
else {
x <- c(x, max(h[i - 1], p[i]))
}
h <- c(h, x[i] + y[i])
}
Thank you very much!!
You don't seem to have a full working example here, but the main problem is that building up the x and h vectors with the c() function is very slow. It's better to preallocate them:
x <- numeric(n) # allocate vector of size n
h <- numeric(n)
and then fill them in as you go by assigning to x[i] and h[i]. For example, the following loop:
x <- c(); for (i in 1:100000) x <- c(x,1)
takes about 10 seconds to run on my laptop, but this version:
x <- numeric(100000); for (i in 1:100000) x[i] <- 1
does the same thing while running almost instantly.
A have code that creates a random graph in the form of a matrix. Now I would like it to create many, say m, random graphs so the output is m matrices. I am trying to do this with a for loop. This would be my preferred method however I am open to other suggestions (apply family?). Here is my code, where n is the number of nodes/vertices the graph has and beta is the amount of preferential attachment (keep this between 0 and 1.5)
multiplerandomgraphs <- function(n, beta, m) {
for(k in 1:m) {
randomgraph <- function(n, beta) {
binfunction <- function(y) {
L <- length(y)
x <- c(0, cumsum(y))
U <- runif(1, min = 0 , max = sum(y))
for(i in 1:L) {
if(x[i] <= U && x[i+1] > U){
return(i)
}
}
}
mat <- matrix(0,n,n)
mat[1,2] <- 1
mat[2,1] <- 1
for(i in 3:n) {
degvect <- colSums(mat[ , (1:(i-1))])
degvect <- degvect^(beta)
j <- binfunction(degvect)
mat[i,j] <- 1
mat[j,i] <- 1
}
return(mat)
}
}
}
You can define your randomgraph function as randomgraph <- function(i, n, beta) {} with the body the same as your definition, leaves the parameter i as a dummy parameter. And then use apply function as listOfMatrix <- lapply(1:m, randomgraph, n, beta) which return a list of matrix.
I'd like to perform this function on a matrix 100 times. How can I do this?
v = 1
m <- matrix(0,10,10)
rad <- function(x) {
idx <- sample(length(x), size=1)
flip = sample(0:1,1,rep=T)
if(flip == 1) {
x[idx] <- x[idx] + v
} else if(flip == 0) {
x[idx] <- x[idx] - v
return(x)
}
}
This is what I have so far but doesn't work.
for (i in 1:100) {
rad(m)
}
I also tried this, which seemed to work, but gave me an output of like 5226 rows for some reason. The output should just be a 10X10 matrix with changed values depending on the conditions of the function.
reps <- unlist(lapply(seq_len(100), function(x) rad(m)))
Ok I think I got it.
The return statement in your function is only inside a branch of an if statement, so it returns a matrix with a probability of ~50% while in the other cases it does not return anything; you should change the code function into this:
rad <- function(x) {
idx <- sample(length(x), size=1)
flip = sample(0:1,1,rep=T)
if(flip == 1) {
x[idx] <- x[idx] + v
} else if(flip == 0) {
x[idx] <- x[idx] - v
}
return(x)
}
Then you can do:
for (i in 1:n) {
m <- rad(m)
}
Note that this is semantically equal to:
for (i in 1:n) {
tmp <- rad(m) # return a modified verion of m (m is not changed yet)
# and put it into tmp
m <- tmp # set m equal to tmp, then in the next iteration we will
# start from a modified m
}
When you run rad(m) is not do changes on m.
Why?
It do a local copy of m matrix and work on it in the function. When function end it disappear.
Then you need to save what function return.
As #digEmAll write the right code is:
for (i in 1:100) {
m <- rad(m)
}
You don't need a loop here. The whole operation can be vectorized.
v <- 1
m <- matrix(0,10,10)
n <- 100 # number of random replacements
idx <- sample(length(m), n, replace = TRUE) # indices
flip <- sample(c(-1, 1), n, replace = TRUE) # subtract or add
newVal <- aggregate(v * flip ~ idx, FUN = sum) # calculate new values for indices
m[newVal[[1]]] <- m[newVal[[1]]] + newVal[[2]] # add new values