## do w/o a loop? (presumably an each question)

Learning APL or new to Dyalog? Ask "silly" questions here, without fear...

### do w/o a loop? (presumably an each question)

stuck on this abstraction of a bigger problem:

a←4 2 ⍴⍳8
b←3 2⍴1 1 1 2 2 3

i want to generate a×[2]b[i;] where i loops thru the rows of b.

this works: ↑, ⍉(↓a)∘.×↓b

but i gotta believe there's a better way than using split and an outer product. i just haven't been able to figure it out. any help? thanks
Last edited by drothman on Thu Jun 18, 2020 1:07 pm, edited 1 time in total.
drothman

Posts: 7
Joined: Fri Feb 06, 2015 3:03 pm

### Re: do w/o a loop? (presumably an each question)

Code: Select all
`     ⎕IO←1     ,[1 2]a×[2]⍤99 ¯1⊢b`

I believe this does the same and unless there are major optimisations in the interpreter it's likely to have the same performance as your version if it's not slower.

As an aside, if ⎕IO needs to die, then the only possibility is to keep it at 1 unless people volunteer to rewrite and test a few millions of lines of code.

StefanoLanzavecchia

Posts: 85
Joined: Fri Oct 03, 2008 9:37 am

### Re: do w/o a loop? (presumably an each question)

`      ↑,b,.×⍉a 0  1 2  3 4  5 6  7 0  2 2  6 4 10 6 14 0  3 4  9 8 1512 21`
But ravel is redundant with a single axis as the axis spec combines a number of axes as one or adds new axes if fractional.

Phil Last

Posts: 571
Joined: Thu Jun 18, 2009 6:29 pm

### Re: do w/o a loop? (presumably an each question)

Nice.

StefanoLanzavecchia

Posts: 85
Joined: Fri Oct 03, 2008 9:37 am

### Re: do w/o a loop? (presumably an each question)

thanks to each of you.

Stefano, would u mind walking me through your solution?

Phil, that's more inline with what i was going for.

again, thanks guys
drothman

Posts: 7
Joined: Fri Feb 06, 2015 3:03 pm

### Re: do w/o a loop? (presumably an each question)

The rank operator is a way to change the way functions (be they primitives or user defined) see their arguments. By specifying rank 99 (-1) you are telling the executor that the left argument should be passed in its entirety whereas the right argument should be passed line by line. So times with axis 2 (x[2]) sees the whole of "a" as its left argument and one line of "b" at a time as its right argument.

Code: Select all
`   ⍴a {⎕←'⍺'⍺'⍵'⍵⋄ ⍺×[2]⍵}⍤ 99 ¯1⊢b⍺ 1 2 ⍵ 1 1   3 4         5 6         7 8       ⍺ 1 2 ⍵ 1 2   3 4         5 6         7 8       ⍺ 1 2 ⍵ 2 3   3 4         5 6         7 8       3 4 2`

If you want, it's a "modern" (v14 onward for Dyalog APL, 30 years for Sharp APL) way to write (⊂a)×[2]¨↓b (which I assume is what you implied in your subject line with "each question"). The rank operator, though, does not nest its results, which get flattened much like a "mix" would do. So the only thing left to do at the end is to ravel together the first two dimensions of the rank 3 array.

StefanoLanzavecchia

Posts: 85
Joined: Fri Oct 03, 2008 9:37 am

### Re: do w/o a loop? (presumably an each question)

thanks. got it. yes,

1. (⊂a)×[2]¨↓b was what i had in mind, but i kept trying to make (↓a)×[2]¨↓b because i'm an apl-1 guy at heart (and haven't coded much in the past few years which is the last time i worked thru some of the apl2 stuff).

2. "The same can be achieved using ⊢ e.g. f⍤1⊢Y because ⍤ binds tighter to its right operand than ⊢ does to its left argument, and ⊢ therefore resolves to Identity." Now noted.

3. "If an item k of B is zero or positive it selects k-cells of the corresponding argument. If it is negative, it selects (r+k)-cells where r is the rank of the corresponding argument. A value of ¯1 selects major cells. " Now noted

good stuff...thanks for the detail.
drothman

Posts: 7
Joined: Fri Feb 06, 2015 3:03 pm

### Re: do w/o a loop? (presumably an each question)

While you already have two working solutions, I'd like to make a slight modification to Stefano's code:
`      ,[⍳2]a×⍤1⍤99 ¯1⊢b 1  2 3  4 5  6 7  8 1  4 3  8 5 12 7 16 2  6 6 1210 1814 24`

This one is ⎕IO-independent and avoids one usage of the bracket axis.

It is worth pointing out that, while elegant, Phil's code still uses nested arrays, and so suffers in speed. Let's scale things a bit:
`      :For f :In 1 3 10       a←(4 2×f)⍴⍳8×f       b←(3 2×f)⍴(/⍨∘⌽⍨⍳3×f)       'Factor:',f       cmpx '↑,⍉(↓a)∘.×↓b' '↑,b,.×⍉a' ',[1 2]a×[2]⍤99 ¯1⊢b' ',[⍳2]a×⍤1⍤99 ¯1⊢b'      :EndForFactor: 1  ↑,⍉(↓a)∘.×↓b        → 2.1E¯6 |    0% ⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕                       ↑,b,.×⍉a            → 4.3E¯6 | +110% ⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕  ,[1 2]a×[2]⍤99 ¯1⊢b → 1.6E¯6 |  -25% ⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕                            ,[⍳2]a×⍤1⍤99 ¯1⊢b   → 1.7E¯6 |  -19% ⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕                        Factor: 3  ↑,⍉(↓a)∘.×↓b        → 1.3E¯5 |    0% ⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕                                ↑,b,.×⍉a            → 5.4E¯5 | +311% ⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕  ,[1 2]a×[2]⍤99 ¯1⊢b → 3.8E¯6 |  -72% ⎕⎕⎕                                       ,[⍳2]a×⍤1⍤99 ¯1⊢b   → 4.1E¯6 |  -69% ⎕⎕⎕                                     Factor: 10  ↑,⍉(↓a)∘.×↓b        → 1.7E¯4 |     0% ⎕⎕⎕                                       ↑,b,.×⍉a            → 2.4E¯3 | +1268% ⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕  ,[1 2]a×[2]⍤99 ¯1⊢b → 2.3E¯5 |   -87%                                           ,[⍳2]a×⍤1⍤99 ¯1⊢b   → 2.4E¯5 |   -87%`

Adam|Dyalog

Posts: 94
Joined: Thu Jun 25, 2015 1:13 pm

### Re: do w/o a loop? (presumably an each question)

There is another equivalent expression:

`      ,[⍳2]a×⍤1⍤99 ¯1⊢b      ⊃ ⍪⌿ ⊂⍤¯1 ⊢a×⍤1⍤99 ¯1⊢b`

This may not seem like an improvement, but had ⍪⌿ been defined differently in Dyalog APL the last expression can be

`      ,[⍳2]a×⍤1⍤99 ¯1⊢b      ⊃ ⍪⌿ ⊂⍤¯1 ⊢a×⍤1⍤99 ¯1⊢b      ⍪⌿ a×⍤1⍤99 ¯1 ⊢b`

The ISO Standard for Extended APL ISO/IEC 13751:2001(E) §9.2.1 specifies two different and incompatible definitions for reduction (AKA insert):Enclose-Reduction-Style (what Dyalog APL and APL2 have) versus Insert-Reduction-Style (Iverson). With the latter, in f⌿⍵, the function operand f is inserted between the major cells of the argument ⍵, and makes for terser expressions in generating subgroups and permutations [Hui and Kromberg 2020, §3.2 and §11.3] as well as inner product reduction (in repeated squaring), etc.

The nested versus boxed array differences between APL2 and the Iverson APLs are well-publicized. IMO, Enclose-Reduction-Style versus Insert-Reduction-Style deserve at least as much attention.
Roger|Dyalog

Posts: 228
Joined: Thu Jul 28, 2011 10:53 am

### Re: do w/o a loop? (presumably an each question)

Even with Enclose-Reduction-Style reduction, if monadic ⍉ been defined as rotating the axes one step instead of reversing them, and we had the Under operator ⍢ then we could also have written:
`      ⍪⍢⍉a×⍤1⍤99 ¯1⊢b`

Adam|Dyalog

Posts: 94
Joined: Thu Jun 25, 2015 1:13 pm

Return to New to Dyalog?

### Who is online

Users browsing this forum: No registered users and 1 guest