tags:

views:

83

answers:

2

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
+2  A: 

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
mbq
@mbq -- Thanks! I considered this, but thought there might be a better way than throwing away the first row. But I think throwing away the first row scales better than an `ifelse`.
richardh
+2  A: 

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)]
    }
}
Loïc Février
OP was afraid this will decrease performance.
mbq
I really doubt that on any modern system an `if` will decrease performance in a visible way (unless we're talking nanoseconds here...), especially with `n=10` and `m=5`.
nico
@nico : yes, if-else really slows down performance, as that is a condition that has to be checked every time. I also doubt that the real problem of OP has the dimensions of this trivial example.
Joris Meys
@Joris Meys: of course it may slow down if n=100000 and m=50000 but then again, I still doubt the `if` would be the bottleneck there. A better optimization would be done for instance avoiding calling `which.max` and `max` (when only one call to `which.max` would suffice).
nico
@nico : very true.
Joris Meys
@nico @joris -- This is for homework, so it really is ten iterations, but I'm looking ahead and trying to build the skills right from day one. The `ifelse` didn't seem like it would scale well. And thanks for pointing out that I can call `which.max` once and kill two birds with one stone. And I thought that I was being slick by using a temp variable to avoid calculating twice! So much to learn. Thanks!
richardh
@richardh : If you're trying to build the skills, you might want to go through this peculiar document : http://www.burns-stat.com/pages/Tutor/R_inferno.pdf . It contains quite a few useful tips for code optimization. Cheers.
Joris Meys