{
"cells": [
{
"cell_type": "markdown",
"id": "5389540e",
"metadata": {},
"source": [
"# `/\\⌿⍀,⍪`\n",
"\n",
"## Replicate `/`\n",
"\n",
"Next up is `/`. When what's on its left is an array rather than a function it instead acts like a function, which makes it unusual. We cover the operator case of `/` elsewhere, e.g. `+/` for sum. \n",
"\n",
"As a function, `/` is called [replicate](http://help.dyalog.com/latest/index.htm#Language/Primitive%20Functions/Replicate.htm). It replicates each element on the right to as many copies as indicated by the corresponding element on the left: "
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "bd597c6c",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"Mississippi\n",
""
]
},
"execution_count": 1,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"1 1 2 1 2 1 2 1/'Misisipi'"
]
},
{
"cell_type": "markdown",
"id": "789969da",
"metadata": {},
"source": [
"A more common usage is with a Boolean left argument, where it then acts as a filter: "
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "04cd201b",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"HllWrld\n",
""
]
},
"execution_count": 2,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"1 0 1 1 0 0 1 0 1 1 1/'Hello World'"
]
},
{
"cell_type": "markdown",
"id": "49669785",
"metadata": {},
"source": [
"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): "
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "30b6f9c8",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"He lo\n",
""
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"1 1 ¯1 1 1/'Hello'"
]
},
{
"cell_type": "markdown",
"id": "3ebc8939",
"metadata": {},
"source": [
"You can also use a single scalar to \"empty\" an array: "
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "640ad948",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
""
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"text/html": [
"abc\n",
""
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"0/'abc'\n",
"1/'abc' "
]
},
{
"cell_type": "markdown",
"id": "b03daffd",
"metadata": {},
"source": [
"`1/x` can also be used to ensure that `x` has at least one dimension (it ravels scalars, leaving all other arrays untouched):"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "1118ca0d",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"1\n",
""
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"text/html": [
"2\n",
""
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"⍴1/8 ⍝ Scalar becomes vector, rank 1\n",
"⍴1/8 8 ⍝ Higher ranks remain untouched"
]
},
{
"cell_type": "markdown",
"id": "3e67312c",
"metadata": {},
"source": [
"## Expand `\\`\n",
"\n",
"`/` has a cousin, `\\`, which, when used as a function, is called [expand](http://help.dyalog.com/latest/index.htm#Language/Primitive%20Functions/Expand.htm).\n",
"\n",
"Positive numbers on the left also replicate like with `/` but negative numbers insert that many prototypical elements at that position:"
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "f426713d",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"1 2 0 3 4 5\n",
""
]
},
"execution_count": 6,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"1 1 ¯1 1 1 1\\1 2 3 4 5"
]
},
{
"cell_type": "markdown",
"id": "b5d8385e",
"metadata": {},
"source": [
"You can use `0` instead of `¯1` which makes it convenient to use Boolean left arguments.\n",
"\n",
"We can now begin to see how we can insert into an array. Let's go back to the problem of inserting 3 in between 2 and 4 in the list 1 2 4 5. Our method was: \n",
"\n",
"Get the indices of the elements: "
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "63866f8e",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"1 2 3 4\n",
""
]
},
"execution_count": 7,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"⍳≢1 2 4 5"
]
},
{
"cell_type": "markdown",
"id": "aa0c4c9e",
"metadata": {},
"source": [
"Look where the index is 2: "
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "3bf3cb31",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"0 1 0 0\n",
""
]
},
"execution_count": 8,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"2=⍳≢1 2 4 5"
]
},
{
"cell_type": "markdown",
"id": "ca5ae8c1",
"metadata": {},
"source": [
"That's where we want to expand: "
]
},
{
"cell_type": "code",
"execution_count": 9,
"id": "6367470d",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"1 2 1 1\n",
""
]
},
"execution_count": 9,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"1+2=⍳≢1 2 4 5"
]
},
{
"cell_type": "markdown",
"id": "4628f2de",
"metadata": {},
"source": [
"Use `\\` to perform the expansion:"
]
},
{
"cell_type": "code",
"execution_count": 10,
"id": "f2e3aa51",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"1 2 2 4 5\n",
""
]
},
"execution_count": 10,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"(1+2=⍳≢1 2 4 5)\\1 2 4 5 "
]
},
{
"cell_type": "markdown",
"id": "41f43f8c",
"metadata": {},
"source": [
"Replace the extra 2 with our desired element: "
]
},
{
"cell_type": "code",
"execution_count": 11,
"id": "24f6abeb",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"1 2 3 4 5\n",
""
]
},
"execution_count": 11,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"3@(1+2)⊢(1+2=⍳≢1 2 4 5)\\1 2 4 5"
]
},
{
"cell_type": "markdown",
"id": "dede5c31",
"metadata": {},
"source": [
"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 `\\`: "
]
},
{
"cell_type": "code",
"execution_count": 14,
"id": "dccfec3f",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"┌──┬───┐\n",
"│AC│ABC│\n",
"│DF│GHI│\n",
"│GI│ │\n",
"└──┴───┘\n",
""
]
},
"execution_count": 14,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"text/html": [
"┌─────┬───┐\n",
"│A BC│ABC│\n",
"│D EF│ │\n",
"│G HI│ │\n",
"│ │DEF│\n",
"│ │GHI│\n",
"└─────┴───┘\n",
""
]
},
"execution_count": 14,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"(1 0 1/3 3⍴⎕A) (1 0 1⌿3 3⍴⎕A)\n",
"(1 ¯2 1 1\\3 3⍴⎕A) (1 ¯2 1 1⍀3 3⍴⎕A)"
]
},
{
"cell_type": "markdown",
"id": "e9bc8379",
"metadata": {},
"source": [
"## Ravel `,`\n",
"\n",
"Monadic `,` [ravels](http://help.dyalog.com/latest/index.htm#Language/Primitive%20Functions/Ravel.htm). It takes all the scalars of an array and makes a single vector (list) out of them. This includes a scalar, so `,3` is a one-element vector:"
]
},
{
"cell_type": "code",
"execution_count": 15,
"id": "33ced6f6",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"ABC\n",
"DEF\n",
"GHI\n",
""
]
},
"execution_count": 15,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"text/html": [
"ABCDEFGHI\n",
""
]
},
"execution_count": 15,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"3 3⍴⎕A\n",
",3 3⍴⎕A"
]
},
{
"cell_type": "markdown",
"id": "7476389f",
"metadata": {},
"source": [
"Question:\n",
"> Isn't that the same as monadic `∊`?\n",
"\n",
"It is not. For example,"
]
},
{
"cell_type": "code",
"execution_count": 16,
"id": "9a1f385d",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"ABCDEFGHI\n",
""
]
},
"execution_count": 16,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"text/html": [
"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\n",
""
]
},
"execution_count": 16,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"∊3 3⍴⎕A\n",
"∊3 3 3⍴⍳27"
]
},
{
"cell_type": "markdown",
"id": "e40e5d23",
"metadata": {},
"source": [
"The difference is that `∊` will take all the data and make it a simple vector. `,` will take all the scalars and make it a (potentially nested) vector:"
]
},
{
"cell_type": "code",
"execution_count": 17,
"id": "5b995934",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"abcdefghijkl\n",
""
]
},
"execution_count": 17,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"text/html": [
"┌───┬───┬───┬───┐\n",
"│abc│def│ghi│jkl│\n",
"└───┴───┴───┴───┘\n",
""
]
},
"execution_count": 17,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"∊2 2⍴'abc' 'def' 'ghi' 'jkl'\n",
",2 2⍴'abc' 'def' 'ghi' 'jkl' "
]
},
{
"cell_type": "markdown",
"id": "fe2a53a1",
"metadata": {},
"source": [
"`∊` is the same as recursive application of `⊃,/`.\n",
"\n",
"## Catenate `,`\n",
"\n",
"Which brings us to dyadic `,`, [catenate](http://help.dyalog.com/latest/index.htm#Language/Primitive%20Functions/Catenate%20Laminate.htm), which is simply concatenation:"
]
},
{
"cell_type": "code",
"execution_count": 18,
"id": "bfae60a4",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"1 2 3 4 5 6\n",
""
]
},
"execution_count": 18,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"1 2 3,4 5 6"
]
},
{
"cell_type": "markdown",
"id": "186e9af2",
"metadata": {},
"source": [
"`,` can also get specified an axis upon which to act: "
]
},
{
"cell_type": "code",
"execution_count": 19,
"id": "e61ac662",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"A B C\n",
"D E F\n",
"1 2 3\n",
"4 5 6\n",
""
]
},
"execution_count": 19,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"text/html": [
"ABC 1 2 3\n",
"DEF 4 5 6\n",
""
]
},
"execution_count": 19,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"(2 3⍴⎕A),[1](2 3⍴⍳6)\n",
"(2 3⍴⎕A),[2](2 3⍴⍳6) "
]
},
{
"cell_type": "markdown",
"id": "a2fb21d2",
"metadata": {},
"source": [
"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:"
]
},
{
"cell_type": "code",
"execution_count": 20,
"id": "bf89ae5f",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"A B C\n",
"D E F\n",
"\n",
"1 2 3\n",
"4 5 6\n",
""
]
},
"execution_count": 20,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"text/html": [
"A B C\n",
"1 2 3\n",
"\n",
"D E F\n",
"4 5 6\n",
""
]
},
"execution_count": 20,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"(2 3⍴⎕A),[0.5](2 3⍴⍳6) ⍝ 3D array\n",
"(2 3⍴⎕A),[1.5](2 3⍴⍳6) ⍝ 3D array "
]
},
{
"cell_type": "markdown",
"id": "a47d81c9",
"metadata": {},
"source": [
"This works for the monadic form too:"
]
},
{
"cell_type": "code",
"execution_count": 21,
"id": "3be1fe61",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"ABC\n",
"DEF\n",
""
]
},
"execution_count": 21,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"text/html": [
"1 2 3\n",
""
]
},
"execution_count": 21,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"text/html": [
"ABC\n",
"\n",
"DEF\n",
""
]
},
"execution_count": 21,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"text/html": [
"2 1 3\n",
""
]
},
"execution_count": 21,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
",[0.5]2 3⍴⎕A\n",
"⍴,[0.5]2 3⍴⎕A\n",
",[1.5]2 3⍴⎕A\n",
"⍴,[1.5]2 3⍴⎕A"
]
},
{
"cell_type": "markdown",
"id": "7f3107fd",
"metadata": {},
"source": [
"## Catenate first `⍪`\n",
"\n",
"Then we have `⍪`. The dyadic `⍪` is a synonym for `,[1]`, and it's sometimes referred to as [catenate first](http://help.dyalog.com/latest/index.htm#Language/Primitive%20Functions/Catenate%20First.htm):"
]
},
{
"cell_type": "code",
"execution_count": 22,
"id": "033e33fe",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"A B C\n",
"D E F\n",
"1 2 3\n",
"4 5 6\n",
""
]
},
"execution_count": 22,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"text/html": [
"A B C\n",
"D E F\n",
"1 2 3\n",
"4 5 6\n",
""
]
},
"execution_count": 22,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"(2 3⍴⎕A),[1](2 3⍴⍳6)\n",
"(2 3⍴⎕A)⍪(2 3⍴⍳6)"
]
},
{
"cell_type": "markdown",
"id": "50c67295",
"metadata": {},
"source": [
"## Table `⍪`\n",
"\n",
"Monadic `⍪` is called [table](http://help.dyalog.com/latest/index.htm#Language/Primitive%20Functions/Table.htm) 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: "
]
},
{
"cell_type": "code",
"execution_count": 24,
"id": "7e3fa653",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"ABCD\n",
"EFGH\n",
"IJKL\n",
"\n",
"MNOP\n",
"QRST\n",
"UVWX\n",
""
]
},
"execution_count": 24,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"text/html": [
"ABCDEFGHIJKL\n",
"MNOPQRSTUVWX\n",
""
]
},
"execution_count": 24,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"2 3 4⍴⎕A\n",
"⍪2 3 4⍴⎕A"
]
},
{
"cell_type": "markdown",
"id": "39fb6a56",
"metadata": {},
"source": [
"That is, monadic `⍪` is just a synonym for `,⍤¯1` (except for scalars). To be universal, we'd need to say `{,⍤¯1⊢1/⍵}`."
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Dyalog APL",
"language": "apl",
"name": "dyalog-kernel"
},
"language_info": {
"file_extension": ".apl",
"mimetype": "text/apl",
"name": "APL"
}
},
"nbformat": 4,
"nbformat_minor": 5
}