Skip to content

Array arithmetic

6 messages · Benilton Carvalho, Henrique Dallazuanna, Gang Chen

#
I have two arrays A and B with dimensions of (L, M, N, P) and (L, M,
N), and I want to do

for (i in 1:L) {
for (j in 1:M) {
for (k in 1:N) {
   if (abs(B[i, j, k]) > 10e-5)  C[i, j, k,] <- A[i, j, k,]/B[i, j, k]
   else C[i, j, k,] <- 0
}
}
}

How can I get C more efficiently than looping?

Thanks,
Gang
#
apparently you forgot the "commented, minimal, self-contained,  
reproducible code" part...

L = 10
M = 20
N = 30
P = 40
set.seed(1)
A = array(rnorm(L*M*N*P), dim=c(L, M, N, P))
B = array(rnorm(L*M*N), dim=c(L, M, N))
B[sample(100, 10)] = 0
C = array(0, dim=c(L, M, N, P))
for (i in 1:L) {
for (j in 1:M) {
for (k in 1:N) {
   if (abs(B[i, j, k]) > 10e-5)  C[i, j, k,] <- A[i, j, k,]/B[i, j, k]
   else C[i, j, k,] <- 0
}
}
}
blah = function(x, y){tmp = x/y; tmp[abs(y) <= 10e-5]=0; return(tmp)}
D = sweep(A, 1:3, B, blah)
identical(C, D)

b
On Mar 6, 2008, at 1:33 PM, Gang Chen wrote:

            
#
I think this should work:

array(A[abs(B) > 10e-5]/B[abs(B) > 10e-5], dim=c(L, M, N, P))
On 06/03/2008, Gang Chen <gangchen6 at gmail.com> wrote:

  
    
#
no, it won't.

you're doing the right math on the "valid" subset... but you're not  
returning the zeros where needed.... therefore, the whole thing will  
get recycled to match the dimensions.

b
On Mar 6, 2008, at 2:03 PM, Henrique Dallazuanna wrote:

            
#
Hum you are rigth, I forgot of 'else'.
On 06/03/2008, Benilton Carvalho <bcarvalh at jhsph.edu> wrote:

  
    
#
Thank both of you for the suggestions!

Gang
On Mar 6, 2008, at 2:12 PM, Henrique Dallazuanna wrote: