Conversation started Dec 13, 2017 at 18:30.
Dec 13, 2017 18:30
Welcome to the APL learning session!
We are proceeding with the functions' marathon. If we are swift, we may be able to finish next week. The first function for today is .
Monadic just takes a simple Boolean array and returns the list of True indices.
⍞←⍸0 1 0 1 1
@Adám 2 4 5
⎕←2 3⍴0 1 0 1 1 0 ⋄ ⎕←⍸2 3⍴0 1 0 1 1 0
@Adám
0 1 0
1 1 0
┌───┬───┬───┐
│1 2│2 1│2 2│
└───┴───┴───┘
A code golf trick: Sum a Boolean array with ≢⍸ instead of +/,
⍞←≢⍸2 3⍴0 1 0 1 1 0
@Adám 3
Dec 13, 2017 18:33
@all Clear?
@Adám only if we use your encoding altering stuff
@EriktheOutgolfer Yeah, that should be implicit by now: Feel free to use Dyalog Unicode, but add <sup>SBCS</sup> after "bytes".
This refers to github.com/abrudz/SBCS which allows you to use the new symbols which are not in the character set.
Dyadic is interval index. It takes a list of sorted arrays on the left, and for each array on the right, tells which "gap" (interval) it belongs.
⍞←1 10 100 1000⍸0 500 2000 3 10
@Adám 0 3 4 1 2
So 0 is in interval number 0 (that is, before 1–10). 500 is in interval 3, which is 100–1000, etc.
And as you can see from 10, it is in interval 2; 10–100. So intervals are [min,max)
For higher rank arrays, it works like grade, i.e. on major cells. See lesson 8.
@all Please interrupt with any questions.
Dyadic is membership. For each scalar in the left argument, return a Boolean if it is a member of the right argument:
⍞←'aeiou'∊'Hello World'
@Adám 0 1 0 1 0
Dec 13, 2017 18:42
Does APL have an "insert at index" command?
@cairdcoinheringaahing You mean to extend the length of the array?
@Adám As in, given an array, an index and a value, insert value at the index in the array. Example: [1, 2, 4, 5], 2, 3 => [1, 2, 3, 4, 5]
@cairdcoinheringaahing There are a couple of approaches:
⍞←∊(⊂,∘3)@2⊢1 2 4 5
@Adám 1 2 3 4 5
This appended a 3 to the 2, then flattened.
You flatten with monadic which is the function we're up to.
Dec 13, 2017 18:47
@Adám That looks too complicated for what I know in APL, but thanks!
@cairdcoinheringaahing If you go over lesson 4 on @ and lesson 7 on it should be pretty obvious how it works.
@cairdcoinheringaahing A more traditional and better performing approach would be:
⍞←{3@(1+2)⊢⍵\⍨1+2=⍳≢⍵}1 2 4 5
@Adám 1 2 3 4 5
But we have not covered the \ function yet.
So, "enlists":
⎕←(⍳3)(2 2⍴⍳4)
Dec 13, 2017 18:51
@Adám
┌─────┬───┐
│1 2 3│1 2│
│     │3 4│
└─────┴───┘
⍞←∊(⍳3)(2 2⍴⍳4)
@Adám 1 2 3 1 2 3 4
Next up is which is (as of yet) only dyadic.
is "Find". It returns a Boolean array of the right argument's shape with a 1 at the "top left" corner of occurrences of the left argument in the right argument:
⍞←'ss'⍷'Mississippi'
@Adám 0 0 1 0 0 1 0 0 0 0 0
The ones here indicate the left "s" wherever "ss" begins.
Dec 13, 2017 18:57
⍞←'--'⍷'---'
@EriktheOutgolfer 1 1 0
@EriktheOutgolfer Yes, overlaps are ok.
Works on high-rank arrays too:
⎕←2 2⍴0 1 0
@Adám
0 1
0 0
@Adám I just investigated if they can be done, and it's useful to only have the top-left corner be a 1 instead of the whole area
⎕←3 3⍴0 1 1 0
Dec 13, 2017 18:58
@Adám
0 1 1
0 0 1
1 0 0
⎕←(2 2⍴0 1 0)⍷(3 3⍴0 1 1 0)
@Adám
1 0 0
0 1 0
0 0 0
@EriktheOutgolfer Yes, otherwise you couldn't detect overlaps.
@Adám of course overlaps can only be done if all chars are equal
@EriktheOutgolfer No:
⍞←'aba'⍷'alababa'
Dec 13, 2017 19:00
@Adám 0 0 1 0 1 0 0
Works on nested arrays too:
⍞←'aa' 'bbb'⍷'c' 'aa' 'bbb' 'dddd' 'aa' 'aa' 'bbb'
@Adám 0 1 0 0 0 1 0
@all Quiz using : Determine if A is a prefix of B.
⍞←'abc' 'def' 'abc'⍷'abc' 'def' 'abc' 'def' 'abc' 'dea' 'ace'
Dec 13, 2017 19:01
@EriktheOutgolfer 1 0 1 0 0 0 0
@Adám ⊃⍷
@EriktheOutgolfer Exactly. Nice!
@Adám ⊃⍷
@H.PWiz Good!
@all How about: Is A a suffix of B?
hm, that's harder
Dec 13, 2017 19:03
@EriktheOutgolfer Yes. We'll get there. Don't worry.
Next function is . It is basically Union of multi-sets.
However, it is symmetrical in a way you can often use to your advantage:
2 messages moved to trash
⎕←'abcc'∪'cda'
@Adám
abccd
⎕←'cda'∪'abcc'
@Adám
cdab
@DyalogAPL um, where is the next line?
@EriktheOutgolfer I probably typed something wrong (like a nbsp instead of a space).
So, anyway, you can see that it preserves duplicates from the left argument, while only adding the items from the right necessary to make the result contain all elements from both.
It will add duplicate elements from the right if they are not in the left, though:
⍞←'abcc'∪'cdda'
Dec 13, 2017 19:08
@Adám abccdd
The monadic is Unique. It simply removes duplicates:
⍞←∪'Mississippi'
@Adám Misp
Unfortunately it only works on vectors (lists) but we will probably extend it to handle major cells soon.
Dyadic is of course intersection, again asymmetric:
⎕←'abcc'∩'cda' ⋄ ⎕←'cda'∩'abcc'
@Adám
acc
ca
So it removes elements from the left which are not in the right. Duplicates in the right do not matter.
The last multi-set function is dyadic ~ which is "without" or "except". It simply removes from the left whatever is on the right. Note that it can take even high-rank right arguments.
⍞←'Mississippi'~'pss'
Dec 13, 2017 19:13
@Adám Miiii
Monadic ~ is logical NOT, simply swapping 1→0 and 0→1:
⎕←(3 3⍴0 1 1 0) (~3 3⍴0 1 1 0)
@Adám
┌─────┬─────┐
│0 1 1│1 0 0│
│0 0 1│1 1 0│
│1 0 0│0 1 1│
└─────┴─────┘
@all How are you all holding up? Too fast?
Next up is /. You may think we covered it in lesson 3 but that was as an operator, e.g. +/ for sum. When what's on its left is an array rather than a function it instead acts like a function. (This does make it unusual.)
/ as a function is called replicate. It replicates each element on the right to as many copies as indicated by the corresponding element on the left:
⍞←1 1 2 1 2 1 2 1/'Misisipi'
@Adám Mississippi
A more common usage is with a Boolean left argument, where it then acts as a filter:
⍞←1 0 1 1 0 0 1 0 1 1 1/'Hello World'
Dec 13, 2017 19:22
@Adám HllWrld
It has one more trick: If you use a negative number, then it replaces the corresponding element with that many prototypes (spaces for characters and zeros for numbers).
⍞←1 1 ¯1 1 1/'Hello'
@Adám He lo
You can also use a single scalar to "empty" and array:
⎕←0/'abc' ⋄ ⎕←1/'abc'
@Adám

abc
/ has a cousin, \ which when used as a function is called "Expand".
Positive numbers on the left also replicate like with / but negative numbers insert that many prototypical elements at that position.
⍞←1 1 ¯1 1 1 1\1 2 3 4 5
Dec 13, 2017 19:29
@Adám 1 2 0 3 4 5
@cairdcoinheringaahing And now you can begin to see how we can insert into an array.
Btw, you can use 0 instead of ¯1 which makes it convenient to use Boolean left arguments.
Let's go back to the problem of inserting 3 in between 2 and 4 in the list 1 2 4 5.
My method was: Get the indices of the elements:
⍞←⍳≢1 2 4 5
@Adám 1 2 3 4
Look where the index is 2:
⍞←2=⍳≢1 2 4 5
@Adám 0 1 0 0
That's where we want to expand:
⍞←1+2=⍳≢1 2 4 5
Dec 13, 2017 19:33
@Adám 1 2 1 1
Do it:
⍞←(1+2=⍳≢1 2 4 5)\1 2 4 5
@Adám 1 2 2 4 5
And then we replace the extra 2 with our desired element:
⍞←3@(1+2)⊢(1+2=⍳≢1 2 4 5)\1 2 4 5
@Adám 1 2 3 4 5
Just like the operators / and \ each have a sibling, and which do the same thing but along the first axis (i.e. on the major cells) so to with the functions / and \ :
⎕←(1 0 1/3 3⍴⎕A) (1 0 1⌿3 3⍴⎕A)
Dec 13, 2017 19:38
@Adám
┌──┬───┐
│AC│ABC│
│DF│GHI│
│GI│   │
└──┴───┘
⎕←(1 ¯2 1 1\3 3⍴⎕A) (1 ¯2 1 1⍀3 3⍴⎕A)
@Adám
┌─────┬───┐
│A  BC│ABC│
│D  EF│   │
│G  HI│   │
│     │DEF│
│     │GHI│
└─────┴───┘
@all Any questions before we move on to , ?
Monadic , ravels. It takes all the scalars of an array and makes a single vector (list) our of them.
This includes a scalar, so ,3 is a one-element vector.
⎕←3 3⍴⎕A
Dec 13, 2017 19:45
@Adám
ABC
DEF
GHI
⎕←,3 3⍴⎕A
@Adám
ABCDEFGHI
@Adám um, isn't that the same as monadic ?
⎕←∊3 3⍴⎕A
@EriktheOutgolfer
ABCDEFGHI
⎕←∊3 3 3⍴⍳27
Dec 13, 2017 19:47
@EriktheOutgolfer
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
@EriktheOutgolfer will take all the data and make it a simple vector. , will take all the scalars and make it a (potentially nested) vector.
⎕←,3 3 3⍴⍳27
⎕←∊2 2⍴'abc' 'def' 'ghi' 'jkl'
@Adám
abcdefghijkl
⎕←,2 2⍴'abc' 'def' 'ghi' 'jkl'
Dec 13, 2017 19:47
@Adám
┌───┬───┬───┬───┐
│abc│def│ghi│jkl│
└───┴───┴───┴───┘
@EriktheOutgolfer is the same as ,/,⊃,/,⊃,/,
@EriktheOutgolfer Clear?
Which brings us to dyadic , which is simply concatenation:
⍞←1 2 3,4 5 6
@Adám 1 2 3 4 5 6
, can also get specified an axis upon which to act:
⎕←(2 3⍴⎕A),[1](2 3⍴⍳6)
Dec 13, 2017 19:52
@Adám
A B C
D E F
1 2 3
4 5 6
⎕←(2 3⍴⎕A),[2](2 3⍴⍳6)
@Adám
ABC 1 2 3
DEF 4 5 6
You can even use fractional axes to specify that you want to concatenate along a new inserted axis between the next lower and higher integer axes:
⎕←(2 3⍴⎕A),[0.5](2 3⍴⍳6) ⍝ 3D array
@Adám
A B C
D E F

1 2 3
4 5 6
⎕←(2 3⍴⎕A),[1.5](2 3⍴⍳6) ⍝ 3D array
Dec 13, 2017 19:54
@Adám
A B C
1 2 3

D E F
4 5 6
This works for the monadic form too:
⎕←,[0.5]2 3⍴⎕A
@Adám
ABC
DEF
⍞←⍴,[0.5]2 3⍴⎕A
@Adám 1 2 3
⎕←,[1.5]2 3⍴⎕A
Dec 13, 2017 19:55
@Adám
ABC

DEF
⍞←⍴,[1.5]2 3⍴⎕A
@Adám 2 1 3
And finally for tonight; :
The dyadic is a synonym for ,[1] :
⎕←(2 3⍴⎕A),[1](2 3⍴⍳6)
@Adám
A B C
D E F
1 2 3
4 5 6
⎕←(2 3⍴⎕A)⍪(2 3⍴⍳6)
Uh.
⎕←(2 3⍴⎕A)⍪(2 3⍴⍳6)
Dec 13, 2017 19:58
@Adám
A B C
D E F
1 2 3
4 5 6
Monadic is called "Table" as it ensures that the result is a table. It ravels the major cells of an array and makes each one of them into a row (i.e. a major cell) of a matrix:
⎕←2 3 4⍴⎕A
@Adám
ABCD
EFGH
IJKL

MNOP
QRST
UVWX
⎕←⍪2 3 4⍴⎕A
@Adám
ABCDEFGHIJKL
MNOPQRSTUVWX
This is, monadic is just a synonym for ,⍤¯1 (except for scalars).
And this concludes today's lesson. See you all next week for the year's last lesson, where will hopefully be able to go through the remaining six functions.
 
Conversation ended Dec 13, 2017 at 20:02.