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)

Postby drothman on Tue Jun 16, 2020 12:52 am

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)

Postby StefanoLanzavecchia on Tue Jun 16, 2020 8:09 am

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.
User avatar
StefanoLanzavecchia
 
Posts: 109
Joined: Fri Oct 03, 2008 9:37 am

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

Postby Phil Last on Tue Jun 16, 2020 9:40 am

      ↑,b,.×⍉a
0 1
2 3
4 5
6 7
0 2
2 6
4 10
6 14
0 3
4 9
8 15
12 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.
User avatar
Phil Last
 
Posts: 624
Joined: Thu Jun 18, 2009 6:29 pm
Location: Wessex

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

Postby StefanoLanzavecchia on Tue Jun 16, 2020 9:45 am

Nice.
User avatar
StefanoLanzavecchia
 
Posts: 109
Joined: Fri Oct 03, 2008 9:37 am

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

Postby drothman on Tue Jun 16, 2020 1:09 pm

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)

Postby StefanoLanzavecchia on Tue Jun 16, 2020 1:38 pm

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.
User avatar
StefanoLanzavecchia
 
Posts: 109
Joined: Fri Oct 03, 2008 9:37 am

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

Postby drothman on Tue Jun 16, 2020 3:10 pm

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)

Postby Adam|Dyalog on Sun Jun 21, 2020 1:40 am

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 12
10 18
14 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'
:EndFor
Factor: 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%
User avatar
Adam|Dyalog
 
Posts: 134
Joined: Thu Jun 25, 2015 1:13 pm

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

Postby Roger|Dyalog on Mon Jun 22, 2020 6:13 pm

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: 238
Joined: Thu Jul 28, 2011 10:53 am

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

Postby Adam|Dyalog on Mon Jun 22, 2020 6:28 pm

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
User avatar
Adam|Dyalog
 
Posts: 134
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