Asher Meir <asher.meir@gmail.com> wrote on 12/29/2011 04:47:21 PM:

> Hello Jean.
> 
> Thank you for your prompt response.
> 
> I have an economic model. I start out with a list of asset levels 
> 1:nks. For every asset level, a person has nis possible income 
> levels and njs possible expense levels, with probabilities pi and 
> pj. They are independent so the probability matrix is just pi%o%pj.
> 
> For each income level, expense level and starting asset level I will
> end up with a specific known utility level next time around. That is
> Vold. I know what Vold[income,expense,new savings level] is. I need 
> a weighted average of these. But the new savings level is itself a 
> function of income, expense and my current saving level.
> 
> So Vnew[current k] = weighted probability of Vold[each income level,
> each expense level, new savings given that income and that expense]
> 
> For simplicity we can say that the ks is i+k-j -- 
income+savings-expenses.
> 
> I don't insist on solving this using the technique I asked about, 
> but that was how I went about approaching the issue. I would welcome
> an alternative algorithm as much as an R fix!
> 
> Many thanks
> Asher


Thanks.  That was helpful.  I created a simple function, ksfunction() to 
represent the example you gave.  I included two additional arguments to 
deal with newly created k values that extend beyond the third dimension of 
your initial array.  Then, I took advantage of the fact that you can 
extract elements from an array using a matrix of indices.

Excerpt from ?"[", the help file on extract: 

"A third form of indexing is via a numeric matrix with the one column for 
each dimension: each row of the index matrix then selects a single element 
of the array, and the result is a vector. Negative indices are not allowed 
in the index matrix. NA and zero values are allowed: rows of an index 
matrix containing a zero are ignored, whereas rows containing an NA 
produce an NA in the result."

In the code below you can see what I did using a very small example for 
the initial array, Vold.  When I increased the size of the array to 100^3, 
the matrix indexing method was 40 times faster than the looping method 
(i.e., it completed in 1/40th the time).

By the way, it's helpful to cc the R-help with all of your replies, so 
that the thread of discussion is maintained for everyone to see.

Hope this helps.

Jean


ksfunction <- function(i, j, k, maxk, def=NA) {
        newk <- i - j + k
        newk <- ifelse(newk < 1 | newk > maxk, def, i - j + k)
        newk
        }

nis <- 5
njs <- 2
nks <- 5
tot <- nis*njs*nks

Vold <- array(seq(tot), c(nis, njs, nks))

old.index <- cbind(i=rep(1:nis, njs*nks), 
        j=rep(rep(1:njs, rep(nis, njs)), nks), 
        k=rep(1:nks, rep(njs*nks, nks)))
new.index <- cbind(old.index[, 1:2], 
        k = ksfunction(old.index[, 1], old.index[, 2], old.index[, 3], 
nks))
Vnew <- array(Vold[new.index], c(nis, njs, nks))


> On Fri, Dec 30, 2011 at 12:32 AM, Jean V Adams <jvadams@usgs.gov> wrote:
> 
> Asher Meir wrote on 12/29/2011 02:58:00 PM:
> 
> 
> > I want to create a new array which selects values from an original 
array
> > based on a function of the indices. That is:
> > 
> > I want to create a new matrix Vnew[i,j,k]=Vold[i,j,ks] where ks is a
> > function of the index elements i,j,k. I want to do this WITHOUT a 
loop.
> > 
> > Call the function "ksfunction", and the array dimensions nis,njs,nks. 
I can
> > do this using a loop as follows:
> > 
> > # Loop version:
> > Vnew<-array(NA,c(nis,njs,nks)
> > for(i1 in 1:nis)for(j1 in 1:njs)for(k1 in
> > 1:nks)Vnew[i1,j1,k1]<-Vold[i1,k1,ksfunction(i1,j1,k1)]
> > 
> > I already know how to create an array of the ks's:
> > ksarray[i,j,k]=ksfunction(i,j,k)  # I have the array ksarray ready
> > 
> > I don't want a loop because nis,njs, and nks are pretty large and it 
takes
> > forever.
> > 
> > Would appreciate help with this issue.
> 
> 
> There may be non-loopy ways to do this, but in order (for me, at 
> least) to suggest something, it would help to know what ksfunction() 
does. 
> 
> Jean 
	[[alternative HTML version deleted]]

