Question

In J (using J503, not J6 or 7), normally when I want to see if the elements of an array are smaller than their predecessor, I use this:

   smaller =: }:<:}.

Which results in n-1 items:

   smaller 1 2 3 4 5
1 1 1 1
   smaller 1 2 4 3
1 1 0

Internally, }: and }. create two arrays (one omits the last item, the other omits the first), finally allowing the <: comparison. The total memory usage will be 2(n-1) for the 2 temp arrays.

   memuse =: 7!:2
   i =: ,(10000#1)?10000
   memuse 'smaller i'
148480

Another approach which should intuitively work better takes more memory:

   smaller2 =: 13 : '2<:/\y.'
   memuse 'smaller i'
214400

(J6 handles this much better. But I'm stuck with J5).

What would be a leaner alternative for the same operation?

Was it helpful?

Solution

Edit:

In J504, using rotate (1|.) seems to be the best choice so far:

smallerS =: <:1&|.
l =: ?. 10000$1000
;memuse &.> 'smaller l';'smaller2 l';'smallerS l'
148480 214400 82880

I would expect

2<:/\y

to be much better, given that 2 f/\y is special code since J 4.06. In the off chance that <: is the reason for the poor performance, try:

0>:2-/\ y
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top