From: Richard Maine on 24 Mar 2010 23:42 Ragu wrote: > I am trying to code whether all non-zero values of a DIM=1 array are > equal. My intention is to avoid writing a O(n**2) loop. I thought of > using intrinsic's pack() and any(). However, I can't seem to get past > the first step. I am not able to select the first element of the array > returned by pack(). You can't subscript an expression. Ever. You can only subscript an array variable. As for how to code what you want, well... I'd say you are working too hard to try to force the whole thing into a single line of code using array expressions. I'll let others try to suggest tricks for that if they want. There's probably a way, but I wouldn't bet on it being either efficient or easy to read. Even if something like > tempval = pack(array, MASK=(array/=0))(1) would work (it won't, for the reason cited above, and as you noted), odds are that it would do something like create the whole temporary array and then pick the first element of it. Heck, it wouldn't be completely implausible for it to create two temporary arrays. Oh, and even if it would otherwise work, that method ignores an obvious "edge condition". Always look for such conditions when coding. If you don't make a habit of looking for them, they will bite you. Think about what would happen if there were no non-zero elements. The "old-fashioned" ways do still exist and are often the best. I'd write it as (untested) tempval = 0. loop_1: do i = 1 , size(array) if (array(i)/=0.) exit loop_1 end do loop_1 if (i<=size(array)) tempval = array(i) all_the_same = all((array==0.) .or. (array==tempval)) I might even be tempted to write that last line as a loop if I was hot for efficiency, but I'm guessing that a decent compiler has at least half a chance of doing it without creating a temporary array. Your odds seem much worse with PACK. (I haven't tested that; its just a speculation). At least it reads clearly. -- Richard Maine | Good judgment comes from experience; email: last name at domain . net | experience comes from bad judgment. domain: summertriangle | -- Mark Twain From: glen herrmannsfeldt on 25 Mar 2010 00:09 Richard Maine wrote: (snip) > The "old-fashioned" ways do still exist and are often the best. I'd > write it as (untested) > tempval = 0. > loop_1: do i = 1 , size(array) > if (array(i)/=0.) exit loop_1 > end do loop_1 > if (i<=size(array)) tempval = array(i) I might have tried one loop, but it might be faster as two. > all_the_same = all((array==0.) .or. (array==tempval)) > I might even be tempted to write that last line as a loop if I was hot > for efficiency, but I'm guessing that a decent compiler has at least > half a chance of doing it without creating a temporary array. Your odds > seem much worse with PACK. (I haven't tested that; its just a > speculation). At least it reads clearly. You mean like two LOGICAL temporary arrays, and then OR together? All these seem to require many passes through the array. How about: logical flag flag=.false. do i=1,size(array) if(flag) then if(array(i).ne.0.and.array(i).ne.temp) ... elseif(array(i).ne.0) then flag=.true. temp=array(i) endif enddo if(.not.flag) ... One pass, and the branch prediction logic might do pretty well on it, too. If the array is small enough to fit in cache, then it probably doesn't matter so much. or, for extra challenge: temp=0 do i=1,size(array) if(array(i).ne.temp) then if(temp.ne.0) ... temp=array(i) endif enddo if(temp.eq.0) ... Also, both of these will stop as soon as two non-equal, non-zero array elements are found. That could be close to the beginning of a large array. Ones that use array intrinsics likely scan through the whole array at least once, likely two or three times. -- glen From: Ragu on 25 Mar 2010 05:37 Thanks Glenn and Richard. The array expression lesson is a good one for me. Good old is still golden.