{ "cells": [ { "cell_type": "raw", "id": "2990f581", "metadata": {}, "source": [ "---\n", "title: \"Operators and axis\"\n", "author: \"Jeremy Howard\"\n", "date: \"2022-07-05\"\n", "categories: [Dyalog, APL, Glyphs]\n", "---" ] }, { "cell_type": "markdown", "id": "5d6af942", "metadata": {}, "source": [ "This post will explore some introductory operators (aka \"higher order functions\") in APL." ] }, { "cell_type": "code", "execution_count": null, "id": "84e8fa35", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
┌→─────────────────────────────────────┐\n", "│Was ON -style=max -trains=tree -fns=on│\n", "└──────────────────────────────────────┘\n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "]box on -style=max -trains=tree -fns=on" ] }, { "cell_type": "markdown", "id": "a627597a", "metadata": {}, "source": [ "## Axis" ] }, { "cell_type": "code", "execution_count": null, "id": "987a8fd9", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
┌→──┐\n", "↓1 2│\n", "│3 4│\n", "│5 6│\n", "└~──┘\n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "3 2⍴⍳6" ] }, { "cell_type": "markdown", "id": "40f2e3e4-4c36-4d16-b121-ae78b8c925ae", "metadata": {}, "source": [ "Axis changes how the equal operator consumes the right argument. We specify a dimesion and we broadcast the operator across that dimension. In this case we are comparing the columns of the array to the left argument." ] }, { "cell_type": "code", "execution_count": null, "id": "b883b3f9", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
┌→──┐\n", "↓1 0│\n", "│0 1│\n", "│1 0│\n", "└~──┘\n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "1 4 5 =[1] 3 2⍴⍳6" ] }, { "cell_type": "code", "execution_count": null, "id": "5161cb08", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
┌→───────┐\n", "↓10 20 30│\n", "│40 50 60│\n", "└~───────┘\n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "⎕←mat ← 2 3 ⍴ 10 20 30 40 50 60 " ] }, { "cell_type": "markdown", "id": "33585019-cee3-48aa-9e51-736e6b3b72aa", "metadata": {}, "source": [ "Similarly we can modify the plus operator to broadcast along the columns." ] }, { "cell_type": "code", "execution_count": null, "id": "8845a1fe", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
┌→───────┐\n", "↓11 21 31│\n", "│42 52 62│\n", "└~───────┘\n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "mat+[1]1 2 ⍝ add along first axis" ] }, { "cell_type": "markdown", "id": "c5e58a1e", "metadata": {}, "source": [ "## Comma functions" ] }, { "cell_type": "markdown", "id": "a445ebe1", "metadata": {}, "source": [ "### `,` (Comma)" ] }, { "cell_type": "markdown", "id": "738a9d5e", "metadata": {}, "source": [ "#### monadic `,` (Ravel)" ] }, { "cell_type": "code", "execution_count": null, "id": "459d3868", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
┌┌→──┐\n", "↓↓1 2│\n", "││3 4│\n", "││ │\n", "││5 6│\n", "││7 8│\n", "└└~──┘\n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "⎕ ← cube ← 2 2 2 ⍴ ⍳8" ] }, { "cell_type": "markdown", "id": "11048033-fdb2-4b95-955a-5a4bccecc05b", "metadata": {}, "source": [ "Returns the elemenst as a vector" ] }, { "cell_type": "code", "execution_count": null, "id": "04f7bdd0", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
┌→──────────────┐\n", "│1 2 3 4 5 6 7 8│\n", "└~──────────────┘\n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ ", cube" ] }, { "cell_type": "code", "execution_count": null, "id": "1cea85bb", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
┌→────────────┐\n", "│ ┌→──┐ ┌→──┐ │\n", "│ │1 2│ │1 2│ │\n", "│ └~──┘ └~──┘ │\n", "└∊────────────┘\n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ ", (1 2)(1 2)" ] }, { "cell_type": "markdown", "id": "f89344a6", "metadata": {}, "source": [ "#### monadic `,` (Ravel) with axis" ] }, { "cell_type": "code", "execution_count": null, "id": "4abc4506", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
┌→──┐\n", "│ABC│\n", "└───┘\n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "'ABC'" ] }, { "cell_type": "markdown", "id": "b7a18e88-4c0f-4600-98e7-d99a9a9a7f14", "metadata": {}, "source": [ "We can use the axis modify insert a new dimension with ravel. We started with a single dimension, and we inserted a new one after it" ] }, { "cell_type": "code", "execution_count": null, "id": "dbb8811f", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
┌→──┐\n", "↓ABC│\n", "└───┘\n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ ",[0.5]'ABC'" ] }, { "cell_type": "code", "execution_count": null, "id": "c5e72477-dc3b-47d6-a414-43201356c711", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
┌→┐\n", "│3│\n", "└~┘\n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "⍴'ABC'" ] }, { "cell_type": "markdown", "id": "bfa13d4b-aee0-49ad-a385-c630203e620d", "metadata": {}, "source": [ "The fraction indicates where the new dimension is inserted" ] }, { "cell_type": "code", "execution_count": null, "id": "6e73a139-fbab-450c-9917-bfeb5402bfe6", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
┌→──┐\n", "│1 3│\n", "└~──┘\n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "⍴,[0.5]'ABC'" ] }, { "cell_type": "markdown", "id": "6f85c20a-fb6b-4ced-adbe-cfbf780fab33", "metadata": {}, "source": [ "If we specify a null dimension the dimension is added at the end" ] }, { "cell_type": "code", "execution_count": null, "id": "f14396b7-187a-4b4a-8cae-126215e1c336", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
┌→──┐\n", "│3 1│\n", "└~──┘\n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "⍴,[⍬]'ABC'" ] }, { "cell_type": "code", "execution_count": null, "id": "8c7c1bcd-2584-41b3-ae81-a2aa4a8eafd2", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
┌┌→──┐\n", "↓↓1 2│\n", "││3 4│\n", "││ │\n", "││5 6│\n", "││7 8│\n", "└└~──┘\n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "2 2 2⍴⍳8" ] }, { "cell_type": "code", "execution_count": null, "id": "d347d249", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
┌┌→──────────┐\n", "↓↓ 1 2 3 4│\n", "││ 5 6 7 8│\n", "││ 9 10 11 12│\n", "││ │\n", "││13 14 15 16│\n", "││17 18 19 20│\n", "││21 22 23 24│\n", "└└~──────────┘\n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "⎕←M ← 2 3 4 ⍴ ⍳24" ] }, { "cell_type": "markdown", "id": "fd03f4b8-12d4-4e4a-8198-3f7dde0b7228", "metadata": {}, "source": [ "Specifying more than one dimension will merge the two given dimensions" ] }, { "cell_type": "code", "execution_count": null, "id": "dbe8d81d", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
┌→──────────┐\n", "↓ 1 2 3 4│\n", "│ 5 6 7 8│\n", "│ 9 10 11 12│\n", "│13 14 15 16│\n", "│17 18 19 20│\n", "│21 22 23 24│\n", "└~──────────┘\n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ ",[1 2]M" ] }, { "cell_type": "code", "execution_count": null, "id": "17fb1de1", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
┌→──┐\n", "│6 4│\n", "└~──┘\n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "⍴,[1 2]M" ] }, { "cell_type": "code", "execution_count": null, "id": "1ef4b061", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
┌→──────────────────────────────────┐\n", "↓ 1 2 3 4 5 6 7 8 9 10 11 12│\n", "│13 14 15 16 17 18 19 20 21 22 23 24│\n", "└~──────────────────────────────────┘\n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ ",[2 3]M" ] }, { "cell_type": "code", "execution_count": null, "id": "0d19a8dd", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
┌→───┐\n", "│2 12│\n", "└~───┘\n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "⍴,[2 3]M" ] }, { "cell_type": "markdown", "id": "69c3dff5", "metadata": {}, "source": [ "#### dyadic `,` (Catenate/Laminate (Join))" ] }, { "cell_type": "markdown", "id": "265f3d8a-6a6a-41f1-a549-407e06fc3fde", "metadata": {}, "source": [ "Joins arrays together" ] }, { "cell_type": "code", "execution_count": null, "id": "da1548a8", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
┌→──────────┐\n", "│1 2 3 4 5 6│\n", "└~──────────┘\n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "1 2 3 , 4 5 6" ] }, { "cell_type": "markdown", "id": "7e9abd02-3f61-4e0f-a379-5d584864c8d7", "metadata": {}, "source": [ "Will be broadcast along the first dimension." ] }, { "cell_type": "code", "execution_count": null, "id": "1ef39154", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
┌┌→─────┐\n", "↓↓1 2 99│\n", "││3 4 99│\n", "││ │\n", "││5 6 99│\n", "││7 8 99│\n", "└└~─────┘\n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "cube ← 2 2 2 ⍴ ⍳8\n", "cube , 99" ] }, { "cell_type": "markdown", "id": "799f29eb-53dc-4bbb-9412-dc67a90847d3", "metadata": {}, "source": [ "#### dyadic `,` (Ravel) with axis" ] }, { "cell_type": "code", "execution_count": null, "id": "56f49ed4-ad6c-4ff0-8800-8f05dd0d263d", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
┌→──┐\n", "↓1 2│\n", "│3 4│\n", "│5 6│\n", "└~──┘\n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "rect←3 2⍴⍳6\n", "rect" ] }, { "cell_type": "code", "execution_count": null, "id": "f0ed7222-4619-4332-8073-22623934751f", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
┌→──┐\n", "│3 2│\n", "└~──┘\n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "⍴rect" ] }, { "cell_type": "markdown", "id": "c6f86ad7-3622-46bb-bb75-e07e81fff150", "metadata": {}, "source": [ "Add the element 10 to the end of each row" ] }, { "cell_type": "code", "execution_count": null, "id": "262a3227-b740-4400-9705-05cdd18d354d", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
┌→─────┐\n", "↓1 2 10│\n", "│3 4 10│\n", "│5 6 10│\n", "└~─────┘\n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "rect,10" ] }, { "cell_type": "markdown", "id": "ad4634e1-1983-419d-857d-eec56d444904", "metadata": {}, "source": [ "We can modify laminate to add the given element to the columns (axis 1) instead of the rows (axis 2)" ] }, { "cell_type": "code", "execution_count": null, "id": "064f6362-ea44-4813-905c-6810f3cca280", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
┌→────┐\n", "↓ 1 2│\n", "│ 3 4│\n", "│ 5 6│\n", "│10 10│\n", "└~────┘\n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "rect,[1]10" ] }, { "cell_type": "markdown", "id": "c69ac56a-5fb4-4a0f-9723-f4d5b05966b7", "metadata": {}, "source": [ "A fractional axis creates a new axis and laminates that onto the existing rect" ] }, { "cell_type": "code", "execution_count": null, "id": "7f789a3b-2223-4cda-826d-112a3800682f", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
┌┌→────┐\n", "↓↓ 1 2│\n", "││ 3 4│\n", "││ 5 6│\n", "││ │\n", "││10 10│\n", "││10 10│\n", "││10 10│\n", "└└~────┘\n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "rect,[0.5]10" ] }, { "cell_type": "code", "execution_count": null, "id": "7ffc9c0b", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
┌→──────┐\n", "↓HEADING│\n", "│-------│\n", "└───────┘\n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "'HEADING',[0.5]'-'" ] }, { "cell_type": "markdown", "id": "393ff183", "metadata": {}, "source": [ "### `⍪` (Comma bar)" ] }, { "cell_type": "markdown", "id": "e39ced39", "metadata": {}, "source": [ "#### monadic `⍪` (Table / Ravel items)\n", "\n", "Very similar to ravel. Operates on the first axis by default instead of the last axis." ] }, { "cell_type": "code", "execution_count": null, "id": "a7fff912", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
┌→┐\n", "↓1│\n", "└~┘\n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "⍪1" ] }, { "cell_type": "markdown", "id": "31a833c1-d54c-4cc1-8d2b-ea0bee670e93", "metadata": {}, "source": [ "This can be used to create columns instead of rows" ] }, { "cell_type": "code", "execution_count": null, "id": "98de0b8e", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
┌→────┐\n", "│ABCDE│\n", "└─────┘\n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" }, { "data": { "text/html": [ "
┌→┐\n", "↓A│\n", "│B│\n", "│C│\n", "│D│\n", "│E│\n", "└─┘\n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "⎕←,5⍴⎕A\n", "⎕←⍪5⍴⎕A" ] }, { "cell_type": "code", "execution_count": null, "id": "4b35b1a5", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
┌┌→───┐\n", "↓↓ABCD│\n", "││EFGH│\n", "││IJKL│\n", "││ │\n", "││MNOP│\n", "││QRST│\n", "││UVWX│\n", "└└────┘\n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "2 3 4⍴⎕A" ] }, { "cell_type": "markdown", "id": "8beb410c-365a-4dd5-bb99-6c78603f8777", "metadata": {}, "source": [ "Ravels the dimensions down to 2 leaving the size of the first dimension unchanged and merging the others." ] }, { "cell_type": "code", "execution_count": null, "id": "8a18842f-7a69-40c1-a3ba-0680e9c97f61", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
┌→───┐\n", "│2 12│\n", "└~───┘\n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "⍴⍪2 3 4⍴⎕A" ] }, { "cell_type": "code", "execution_count": null, "id": "037190ca", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
┌→───────────┐\n", "↓ABCDEFGHIJKL│\n", "│MNOPQRSTUVWX│\n", "└────────────┘\n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "⍪2 3 4⍴⎕A" ] }, { "cell_type": "markdown", "id": "6d2fc7fb", "metadata": {}, "source": [ "#### dyadic `⍪` (Catenate first)" ] }, { "cell_type": "markdown", "id": "98fd1916-3562-49c6-9b67-9810d2d788df", "metadata": {}, "source": [ "Operates by catenating the first dimensions" ] }, { "cell_type": "code", "execution_count": null, "id": "9a7ff5ba", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
┌→──────────┐\n", "│1 2 3 4 5 6│\n", "└~──────────┘\n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "1 2 3 ⍪ 4 5 6" ] }, { "cell_type": "code", "execution_count": null, "id": "ece4e465", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
┌┌→────┐\n", "↓↓ 1 2│\n", "││ 3 4│\n", "││ │\n", "││ 5 6│\n", "││ 7 8│\n", "││ │\n", "││99 99│\n", "││99 99│\n", "└└~────┘\n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "cube ← 2 2 2 ⍴ ⍳8\n", "cube ⍪ 99" ] }, { "cell_type": "markdown", "id": "aff32832", "metadata": {}, "source": [ "## Operator glyphs" ] }, { "cell_type": "markdown", "id": "4a5637bb", "metadata": {}, "source": [ "### `/` (Slash)" ] }, { "cell_type": "markdown", "id": "2280a745", "metadata": {}, "source": [ "#### monadic `/` (Reduce / N-wise Reduce)" ] }, { "cell_type": "markdown", "id": "81deb293", "metadata": {}, "source": [ "##### monadic function (Reduce)" ] }, { "cell_type": "markdown", "id": "4d50e619-25d8-42d0-83f5-886b9403c7e6", "metadata": {}, "source": [ "inserts the function on the right between the elements of the given array\n", "\n", "1 2 3 4 5 ---> 1+2+3+4+5 " ] }, { "cell_type": "code", "execution_count": null, "id": "fe10c50b", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
┌→────────┐\n", "│1 2 3 4 5│\n", "└~────────┘\n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" }, { "data": { "text/html": [ "
\n", "15\n", " \n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "⎕ ← a ← ⍳5\n", "+/a" ] }, { "cell_type": "markdown", "id": "35faa2a5-b69f-4a3e-92da-b7df15055454", "metadata": {}, "source": [ "Can be used to multiply all elements together" ] }, { "cell_type": "code", "execution_count": null, "id": "bdefcfd6", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "120\n", " \n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a ← ⍳5\n", "×/a" ] }, { "cell_type": "code", "execution_count": null, "id": "cd0a05f3", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "1.5\n", " \n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a ← ⍳3\n", "÷/a" ] }, { "cell_type": "markdown", "id": "8d194d1d-d95b-4363-b1ce-412ee09b412e", "metadata": {}, "source": [ "Find the maximum element in an array" ] }, { "cell_type": "code", "execution_count": null, "id": "55830e33", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "6\n", " \n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a ← 4 6 2\n", "⌈/ a" ] }, { "cell_type": "markdown", "id": "4e9da966-92c9-4a62-8293-822e6e773a6f", "metadata": {}, "source": [ "Find the minimum element in the array" ] }, { "cell_type": "code", "execution_count": null, "id": "9bc76d4b", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "2\n", " \n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a ← 4 6 2\n", "⌊/ a" ] }, { "cell_type": "code", "execution_count": null, "id": "1722938f", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "120\n", " \n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "×/⍳5" ] }, { "cell_type": "code", "execution_count": null, "id": "6adcb7d7", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "120\n", " \n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "!5" ] }, { "cell_type": "markdown", "id": "d75ce5c5", "metadata": {}, "source": [ "##### dyadic function (N-wise Reduce)" ] }, { "cell_type": "markdown", "id": "8d680e4f", "metadata": {}, "source": [ "Windowed sum with window of `3`:" ] }, { "cell_type": "code", "execution_count": null, "id": "a4886242", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
┌→──┐\n", "│6 9│\n", "└~──┘\n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "3+/⍳4 ⍝ (1+2+3) (2+3+4)" ] }, { "cell_type": "markdown", "id": "d9925a15", "metadata": {}, "source": [ "Windowed sum with window of `2`:" ] }, { "cell_type": "code", "execution_count": null, "id": "ccb02a6d", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
┌→────┐\n", "│3 5 7│\n", "└~────┘\n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "2+/⍳4 ⍝ (1+2) (2+3) (3+4)" ] }, { "cell_type": "markdown", "id": "4a08d2a9", "metadata": {}, "source": [ "Moving average" ] }, { "cell_type": "code", "execution_count": null, "id": "f38bbd1e", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
┌→──┐\n", "│2 3│\n", "└~──┘\n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "3÷⍨3+/⍳4" ] }, { "cell_type": "code", "execution_count": null, "id": "daf6d8d7", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
┌→────────┐\n", "│0 0 0 0 0│\n", "└~────────┘\n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "0+/⍳4 ⍝ Identity element for +" ] }, { "cell_type": "code", "execution_count": null, "id": "f7f84184", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
┌→────────┐\n", "│1 1 1 1 1│\n", "└~────────┘\n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "0×/⍳4 ⍝ Identity element for ×" ] }, { "cell_type": "code", "execution_count": null, "id": "a38d586d", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
┌→──────────────────┐\n", "│ ┌→──┐ ┌→──┐ ┌→──┐ │\n", "│ │2 1│ │3 2│ │4 3│ │\n", "│ └~──┘ └~──┘ └~──┘ │\n", "└∊──────────────────┘\n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "¯2,/⍳4⍝ (2,1) (3,2) (4,3)" ] }, { "cell_type": "markdown", "id": "9e75d568", "metadata": {}, "source": [ "#### Axis (with Monadic Operand)" ] }, { "cell_type": "markdown", "id": "31dd5a83-b6bd-4631-8e91-9d1713f00ae5", "metadata": {}, "source": [ "Combining reduce with axis allows us to specify the dimension to reduce. \n", "\n", "Sum the columns" ] }, { "cell_type": "code", "execution_count": null, "id": "3f53c64f", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
┌→────┐\n", "│5 7 9│\n", "└~────┘\n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "mat←2 3⍴⍳6\n", "+/[1]mat" ] }, { "cell_type": "markdown", "id": "57a1e5d3-978e-4ba4-a8f2-d6f125e5cfe8", "metadata": {}, "source": [ "Sum the rows" ] }, { "cell_type": "code", "execution_count": null, "id": "8afa5145", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
┌→───┐\n", "│6 15│\n", "└~───┘\n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "mat←2 3⍴⍳6\n", "+/[2]mat" ] }, { "cell_type": "code", "execution_count": null, "id": "9fa2ebcb", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
┌→───┐\n", "│6 15│\n", "└~───┘\n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "mat←2 3⍴⍳6\n", "+/mat" ] }, { "cell_type": "markdown", "id": "773b883b", "metadata": {}, "source": [ "### `\\` (Slope)" ] }, { "cell_type": "markdown", "id": "89401d1e", "metadata": {}, "source": [ "#### monadic `\\` (Scan)" ] }, { "cell_type": "markdown", "id": "228481ac-b655-4c6a-88b8-790ee11fb81f", "metadata": {}, "source": [ "Show all the intermediate steps of reduce\n", "\n", "1 (1+2) (1+2+3) (1+2+3+4) (1+2+3+4+5)" ] }, { "cell_type": "code", "execution_count": null, "id": "cad6c863", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
┌→──────────┐\n", "│1 3 6 10 15│\n", "└~──────────┘\n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a ← ⍳5\n", "+\\a" ] }, { "cell_type": "code", "execution_count": null, "id": "3e093072", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
┌→───────────┐\n", "│1 2 6 24 120│\n", "└~───────────┘\n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a ← ⍳5\n", "×\\a" ] }, { "cell_type": "code", "execution_count": null, "id": "5ea8bd1b", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
┌→────┐\n", "│1 2 3│\n", "└~────┘\n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" }, { "data": { "text/html": [ "
┌→────────┐\n", "│1 0.5 1.5│\n", "└~────────┘\n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "⎕ ← a ← ⍳3\n", "÷\\a" ] }, { "cell_type": "markdown", "id": "fc3c7818", "metadata": {}, "source": [ "### `⌿` (Slash Bar)" ] }, { "cell_type": "markdown", "id": "aeb4f2da", "metadata": {}, "source": [ "#### monadic `⌿` (Reduce First)\n", "\n", "Works similar to reduce. Operates on the first dimension rather than the last." ] }, { "cell_type": "code", "execution_count": null, "id": "152dad7d", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
┌→────┐\n", "↓1 2 3│\n", "│4 5 6│\n", "└~────┘\n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" }, { "data": { "text/html": [ "
┌→───┐\n", "│6 15│\n", "└~───┘\n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "⎕←mat ← 2 3 ⍴ ⍳6\n", "+/mat" ] }, { "cell_type": "code", "execution_count": null, "id": "d65f9e59", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
┌→────┐\n", "↓1 2 3│\n", "│4 5 6│\n", "└~────┘\n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" }, { "data": { "text/html": [ "
┌→────┐\n", "│5 7 9│\n", "└~────┘\n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "⎕←mat ← 2 3 ⍴ ⍳6\n", "+/[1]mat" ] }, { "cell_type": "code", "execution_count": null, "id": "5129c061", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
┌→────┐\n", "│5 7 9│\n", "└~────┘\n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "+⌿mat" ] }, { "cell_type": "markdown", "id": "8437a76a", "metadata": {}, "source": [ "### `⍀` (Slope Bar)" ] }, { "cell_type": "markdown", "id": "dbfdb8bc", "metadata": {}, "source": [ "#### monadic `⍀` (Scan first)" ] }, { "cell_type": "markdown", "id": "48b9a87b-f141-489d-bf6f-312df0ddb702", "metadata": {}, "source": [ "Similar to scan but operates on the first dimension rather than the last" ] }, { "cell_type": "code", "execution_count": null, "id": "0d0d0e4b", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
┌→────┐\n", "↓1 2 3│\n", "│4 5 6│\n", "└~────┘\n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" }, { "data": { "text/html": [ "
┌→────┐\n", "↓1 2 3│\n", "│5 7 9│\n", "└~────┘\n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "⎕ ← mat ← 2 3 ⍴ ⍳6\n", "+⍀mat" ] }, { "cell_type": "markdown", "id": "c683f047", "metadata": {}, "source": [ "### `⍤` (Jot Diaresis)" ] }, { "cell_type": "markdown", "id": "5bc89ad4", "metadata": {}, "source": [ "#### dyadic `⍤` (Rank)" ] }, { "cell_type": "code", "execution_count": null, "id": "e1615c86-fccd-4d7c-b131-e8dac79b3dcd", "metadata": {}, "outputs": [], "source": [ "trace←{⍺←⊢⋄⎕←'⍺: '⍺ '⍵: '⍵⋄ ⍺ ⍺⍺ ⍵} ⍝ explainer function" ] }, { "cell_type": "markdown", "id": "46b6787b-09f9-4e5e-8bba-3d8b4ca762ac", "metadata": {}, "source": [ "⍤ lets you specify the dimensions of the matrix to pass into the next function. In this case we only want plus reduce first to operate across rows." ] }, { "cell_type": "code", "execution_count": null, "id": "8101e7f2", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
┌┌→──────────┐\n", "↓↓ 1 2 3 4│\n", "││ 5 6 7 8│\n", "││ 9 10 11 12│\n", "││ │\n", "││13 14 15 16│\n", "││17 18 19 20│\n", "││21 22 23 24│\n", "└└~──────────┘\n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" }, { "data": { "text/html": [ "
┌→───────┐\n", "↓10 26 42│\n", "│58 74 90│\n", "└~───────┘\n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "⎕←cube ← 2 3 4 ⍴ ⍳24\n", "(+⌿⍤1)cube" ] }, { "cell_type": "code", "execution_count": null, "id": "f25f52cc-403d-46ff-8228-f6edfc1615ca", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
┌→────────────────┐\n", "│ ┌→──┐ ┌→──────┐ │\n", "│ │⍵: │ │1 2 3 4│ │\n", "│ └───┘ └~──────┘ │\n", "└∊────────────────┘\n", "┌→────────────────┐\n", "│ ┌→──┐ ┌→──────┐ │\n", "│ │⍵: │ │5 6 7 8│ │\n", "│ └───┘ └~──────┘ │\n", "└∊────────────────┘\n", "┌→───────────────────┐\n", "│ ┌→──┐ ┌→─────────┐ │\n", "│ │⍵: │ │9 10 11 12│ │\n", "│ └───┘ └~─────────┘ │\n", "└∊───────────────────┘\n", "┌→────────────────────┐\n", "│ ┌→──┐ ┌→──────────┐ │\n", "│ │⍵: │ │13 14 15 16│ │\n", "│ └───┘ └~──────────┘ │\n", "└∊────────────────────┘\n", "┌→────────────────────┐\n", "│ ┌→──┐ ┌→──────────┐ │\n", "│ │⍵: │ │17 18 19 20│ │\n", "│ └───┘ └~──────────┘ │\n", "└∊────────────────────┘\n", "┌→────────────────────┐\n", "│ ┌→──┐ ┌→──────────┐ │\n", "│ │⍵: │ │21 22 23 24│ │\n", "│ └───┘ └~──────────┘ │\n", "└∊────────────────────┘\n", "┌→───────┐\n", "↓10 26 42│\n", "│58 74 90│\n", "└~───────┘\n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(+⌿trace⍤1)cube ⍝ show the input to pluse reduce first" ] }, { "cell_type": "markdown", "id": "b910a81b-0aef-45de-a534-03bb6b071e32", "metadata": {}, "source": [ "Sum the columns" ] }, { "cell_type": "code", "execution_count": null, "id": "abfe1dad", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
┌→─────────┐\n", "↓1 2 3 4│\n", "│5 6 7 8│\n", "│9 10 11 12│\n", "└~─────────┘\n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" }, { "data": { "text/html": [ "
┌→──────────┐\n", "│15 18 21 24│\n", "└~──────────┘\n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "⎕←mat ← 3 4 ⍴ ⍳12\n", "+⌿mat" ] }, { "cell_type": "markdown", "id": "a19736ef-768a-465d-9667-f7d68e539add", "metadata": {}, "source": [ "For each of the 3 4 (the first 2 dimensions) matrices in the larger cube apply plus reduce first" ] }, { "cell_type": "code", "execution_count": null, "id": "3caf9370", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
┌┌→──────────┐\n", "↓↓ 1 2 3 4│\n", "││ 5 6 7 8│\n", "││ 9 10 11 12│\n", "││ │\n", "││13 14 15 16│\n", "││17 18 19 20│\n", "││21 22 23 24│\n", "└└~──────────┘\n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" }, { "data": { "text/html": [ "
┌→──────────┐\n", "↓15 18 21 24│\n", "│51 54 57 60│\n", "└~──────────┘\n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "⎕←cube\n", "(+⌿⍤2)cube" ] }, { "cell_type": "markdown", "id": "bc636c48-b859-443a-be50-bee227a444d4", "metadata": {}, "source": [ "Given ⍺ and ⍵ arguments we can specify dimensions for each. In the following we take the ⍺ argument by element and the ⍵ argument by row" ] }, { "cell_type": "code", "execution_count": null, "id": "63cefbe6", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
┌→─────────┐\n", "↓1 2 3 4│\n", "│5 6 7 8│\n", "│9 10 11 12│\n", "└~─────────┘\n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" }, { "data": { "text/html": [ "
┌→────────────────────────┐\n", "│ ┌→──┐ ┌→──┐ ┌→──────┐ │\n", "│ │⍺: │ 1 │⍵: │ │1 2 3 4│ │\n", "│ └───┘ └───┘ └~──────┘ │\n", "└∊────────────────────────┘\n", "┌→────────────────────────┐\n", "│ ┌→──┐ ┌→──┐ ┌→──────┐ │\n", "│ │⍺: │ 2 │⍵: │ │5 6 7 8│ │\n", "│ └───┘ └───┘ └~──────┘ │\n", "└∊────────────────────────┘\n", "┌→───────────────────────────┐\n", "│ ┌→──┐ ┌→──┐ ┌→─────────┐ │\n", "│ │⍺: │ 3 │⍵: │ │9 10 11 12│ │\n", "│ └───┘ └───┘ └~─────────┘ │\n", "└∊───────────────────────────┘\n", "┌→──────────┐\n", "↓ 2 3 4 5│\n", "│ 7 8 9 10│\n", "│12 13 14 15│\n", "└~──────────┘\n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "⎕←mat\n", "1 2 3 (+trace⍤0 1) mat" ] }, { "cell_type": "markdown", "id": "10d5153b", "metadata": {}, "source": [ "#### dyadic `⍤` (Atop)" ] }, { "cell_type": "markdown", "id": "1d61412e-1612-4414-8b9b-9d7832614717", "metadata": {}, "source": [ "⍤ used dyadically is a function application rule\n", "\n", " f⍤g X → f(gX) → fgX\n", "X f⍤g Y → f X g Y" ] }, { "cell_type": "code", "execution_count": null, "id": "96480209", "metadata": {}, "outputs": [], "source": [ "f ← *⍤÷" ] }, { "cell_type": "code", "execution_count": null, "id": "07dfbebb", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "1.395612425\n", " \n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" }, { "data": { "text/html": [ "
\n", "1.395612425\n", " \n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "⎕←*(÷3)\n", "⎕←f 3" ] }, { "cell_type": "code", "execution_count": null, "id": "35d3df26", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "1.947734041\n", " \n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" }, { "data": { "text/html": [ "
\n", "1.947734041\n", " \n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "⎕←*2÷3\n", "⎕←2 f 3" ] }, { "cell_type": "markdown", "id": "618ab13f", "metadata": {}, "source": [ "### `∘` (Jot)" ] }, { "cell_type": "markdown", "id": "75b436ce", "metadata": {}, "source": [ "#### dyadic `∘` (Bind)" ] }, { "cell_type": "markdown", "id": "d6cc9efc-5074-440a-a60b-a50fdd7bae16", "metadata": {}, "source": [ "Can be used for partial function application. Binds the right argument 2 to the power function returning a new function that takes only a single argument" ] }, { "cell_type": "code", "execution_count": null, "id": "c231621a", "metadata": {}, "outputs": [], "source": [ "sqr ← *∘2" ] }, { "cell_type": "code", "execution_count": null, "id": "b7cbacfb", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "9\n", " \n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "sqr 3" ] }, { "cell_type": "markdown", "id": "976e5348-92e4-4aca-8f2a-4f9be263eaf6", "metadata": {}, "source": [ "Can bind the left argument as well" ] }, { "cell_type": "code", "execution_count": null, "id": "d0b9f0b1", "metadata": {}, "outputs": [], "source": [ "pow2 ← 2∘*" ] }, { "cell_type": "code", "execution_count": null, "id": "2d432fe5", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "8\n", " \n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "pow2 3" ] }, { "cell_type": "markdown", "id": "e6c3fd06", "metadata": {}, "source": [ "#### dyadic `∘` (Beside)" ] }, { "cell_type": "markdown", "id": "3e1d27a7-41a1-4877-addf-18e5815da6f7", "metadata": {}, "source": [ "Another function composition rule\n", "\n", " f∘g X → f(gX) → fgX\n", "X f∘g Y → X f g Y" ] }, { "cell_type": "code", "execution_count": null, "id": "514cfaf5", "metadata": {}, "outputs": [], "source": [ "f ← *∘÷" ] }, { "cell_type": "code", "execution_count": null, "id": "547aa92a", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "1.395612425\n", " \n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "*(÷3)" ] }, { "cell_type": "code", "execution_count": null, "id": "6c9ab7db", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "1.395612425\n", " \n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "f 3" ] }, { "cell_type": "code", "execution_count": null, "id": "1c92fcab", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "1.25992105\n", " \n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "2 f 3" ] }, { "cell_type": "code", "execution_count": null, "id": "88b61671", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "1.25992105\n", " \n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "2 * (÷3)" ] }, { "cell_type": "code", "execution_count": null, "id": "be94480f", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "1.25992105\n", " \n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "2*÷3" ] }, { "cell_type": "markdown", "id": "cd58ec37", "metadata": {}, "source": [ "### `⍥` (Circle diaresis)" ] }, { "cell_type": "markdown", "id": "3397ffbc", "metadata": {}, "source": [ "#### dyadic `⍥` (Over)" ] }, { "cell_type": "markdown", "id": "4829d654-8512-4b55-b581-73af812150dd", "metadata": {}, "source": [ "Another function composition rule. \n", "\n", "\n", " f⍥g Y → f(gX) → fgX\n", "X f⍥g Y → (g X)f(g Y)" ] }, { "cell_type": "code", "execution_count": null, "id": "15503ed8", "metadata": {}, "outputs": [], "source": [ "f ← *⍥÷" ] }, { "cell_type": "code", "execution_count": null, "id": "39400248", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "1.395612425\n", " \n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "*(÷3)" ] }, { "cell_type": "code", "execution_count": null, "id": "4b9b1a63", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "1.395612425\n", " \n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "f 3" ] }, { "cell_type": "code", "execution_count": null, "id": "ebb9611d", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "0.793700526\n", " \n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "2 f 3" ] }, { "cell_type": "code", "execution_count": null, "id": "e9005d9d", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "0.793700526\n", " \n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(÷2)*÷3" ] }, { "cell_type": "code", "execution_count": null, "id": "f983a246", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "5040\n", " \n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "10 (÷⍥!) 6 ⍝ P(10,4)" ] }, { "cell_type": "code", "execution_count": null, "id": "85da6f8e", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "5040\n", " \n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(!10)÷!(10-4) ⍝ P(10,4)" ] }, { "cell_type": "markdown", "id": "13f6bdc4", "metadata": {}, "source": [ "### `⍣` (Star Diaeresis)" ] }, { "cell_type": "markdown", "id": "06e52bcd", "metadata": {}, "source": [ "#### dyadic `⍣` (Power operator)" ] }, { "cell_type": "code", "execution_count": null, "id": "e5aeb826", "metadata": {}, "outputs": [], "source": [ "S ← +∘1" ] }, { "cell_type": "code", "execution_count": null, "id": "94a44e68", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "1\n", " \n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "S 0" ] }, { "cell_type": "markdown", "id": "da840ec8-0488-4e54-864a-920ad26f1293", "metadata": {}, "source": [ "⍣ Calls a function the given number of times.\n", "\n", "S(S(S 0))" ] }, { "cell_type": "code", "execution_count": null, "id": "0f8dd750", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "3\n", " \n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(S⍣3) 0" ] }, { "cell_type": "code", "execution_count": null, "id": "9f9daf8a", "metadata": {}, "outputs": [], "source": [ "add ← {(S⍣⍺) ⍵}" ] }, { "cell_type": "code", "execution_count": null, "id": "b9e9a45c", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "5\n", " \n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "2 add 3" ] }, { "cell_type": "code", "execution_count": null, "id": "96858617", "metadata": {}, "outputs": [], "source": [ "mult ← {⍺ (add⍣⍵) 0}" ] }, { "cell_type": "code", "execution_count": null, "id": "fcefb1db", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "12\n", " \n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "3 mult 4" ] }, { "cell_type": "code", "execution_count": null, "id": "804d9c16", "metadata": {}, "outputs": [], "source": [ "P ← S⍣¯1" ] }, { "cell_type": "code", "execution_count": null, "id": "faa5c23e", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "2\n", " \n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "P 3" ] }, { "cell_type": "code", "execution_count": null, "id": "bb4c25cf", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "2\n", " \n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(S⍣¯3) 5" ] }, { "cell_type": "code", "execution_count": null, "id": "d66c5206", "metadata": {}, "outputs": [], "source": [ "sqr ← *∘2" ] }, { "cell_type": "code", "execution_count": null, "id": "f2e08283", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "3\n", " \n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(sqr⍣¯1)9" ] }, { "cell_type": "code", "execution_count": null, "id": "8fc3dc3e", "metadata": {}, "outputs": [], "source": [ "pow ← {⍺ (mult⍣⍵) 1}" ] }, { "cell_type": "code", "execution_count": null, "id": "64d80892", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "8\n", " \n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "2 pow 3" ] }, { "cell_type": "code", "execution_count": null, "id": "b929e29d", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "1.618033989\n", " \n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "1 +∘÷⍣= 1" ] }, { "cell_type": "code", "execution_count": null, "id": "c008024b", "metadata": {}, "outputs": [], "source": [ "f ← +∘÷" ] }, { "cell_type": "code", "execution_count": null, "id": "0fef609d", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "2\n", " \n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "1 f 1" ] }, { "cell_type": "code", "execution_count": null, "id": "26420a6e", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "1.5\n", " \n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "1 f 2" ] }, { "cell_type": "code", "execution_count": null, "id": "abbd9af4", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "1.666666667\n", " \n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "1 f 1.5" ] }, { "cell_type": "code", "execution_count": null, "id": "61e500d3", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "1.618034448\n", " \n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "1 (f⍣15) 1" ] }, { "cell_type": "code", "execution_count": null, "id": "7749b6a9", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "1.618033989\n", " \n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "1 (f⍣=) 1" ] }, { "cell_type": "markdown", "id": "6d32ee42", "metadata": {}, "source": [ "## Linear Algebra" ] }, { "cell_type": "markdown", "id": "85f3061a", "metadata": {}, "source": [ "### `.` (Dot)" ] }, { "cell_type": "markdown", "id": "471ba9ed", "metadata": {}, "source": [ "#### Dyadic `.` (Inner Product)" ] }, { "cell_type": "markdown", "id": "f0c8e79e-1aaf-47b2-980d-1d5c590b513c", "metadata": {}, "source": [ "The ⍵⍵ operator specifies how elements are combined. The ⍺⍺ argument specifies how the results of the ⍵⍵ operation are combined." ] }, { "cell_type": "markdown", "id": "67ed7a8f-5da7-42d0-a97e-447f8e6afe7c", "metadata": {}, "source": [ "(1×4) + (2×5) + (3×6)" ] }, { "cell_type": "code", "execution_count": null, "id": "68dbc16f", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "32\n", " \n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "1 2 3 +.× 4 5 6 ⍝ Dot product" ] }, { "cell_type": "markdown", "id": "fa57e7fc-1496-4a14-a9fa-97393edf1bb2", "metadata": {}, "source": [ "(3=3)∧(3=3)∧(3=3)∧(3=3)" ] }, { "cell_type": "code", "execution_count": null, "id": "afb1c2cf", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "1\n", " \n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "3 ∧.= 3 3 3 3 ⍝ All-equal" ] }, { "cell_type": "markdown", "id": "7df63fab-6cf8-4983-a0b5-9bf8d3c95213", "metadata": {}, "source": [ "(1×1)+(2×3) (1×2)+(2×4)\n", "\n", "(3×1)+(4×3) (3×2)+(4×4)" ] }, { "cell_type": "code", "execution_count": null, "id": "a74f3e9c", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
┌→──┐\n", "↓1 2│\n", "│3 4│\n", "└~──┘\n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" }, { "data": { "text/html": [ "
┌→────┐\n", "↓ 7 10│\n", "│15 22│\n", "└~────┘\n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "⎕←mat←2 2⍴⍳4\n", "mat +.× mat ⍝ matrix product" ] }, { "cell_type": "markdown", "id": "0f466a96-4746-4484-84da-8ac7d9aa4c98", "metadata": {}, "source": [ "In this case we are going to duplicate the ⍵ argument. Once for each element of the ⍺ argument. The first one is multiplied by the first element of the ⍺ argument. The second by the second element, etc.\n", "\n", "1× 4 5 6 7\n", "\n", "2× 4 5 6 7\n", "\n", "3× 4 5 6 7" ] }, { "cell_type": "code", "execution_count": null, "id": "c79a3d12", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
┌→──────────┐\n", "↓ 4 5 6 7│\n", "│ 8 10 12 14│\n", "│12 15 18 21│\n", "└~──────────┘\n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "1 2 3 ∘.× 4 5 6 7 ⍝ Special case: outer prodct" ] }, { "cell_type": "markdown", "id": "d60de628", "metadata": {}, "source": [ "### `⌹` (Domino;Quad Divide)" ] }, { "cell_type": "markdown", "id": "499ddf80", "metadata": {}, "source": [ "#### Monadic `⌹` (Matrix Inverse Of)" ] }, { "cell_type": "code", "execution_count": null, "id": "3ae7e56b", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
┌→────────┐\n", "↓¯2 1 │\n", "│ 1.5 ¯0.5│\n", "└~────────┘\n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "mat←2 2⍴⍳4\n", "⎕←inv←⌹ mat" ] }, { "cell_type": "code", "execution_count": null, "id": "465cc80b", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
┌→──┐\n", "↓1 0│\n", "│0 1│\n", "└~──┘\n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "inv +.× mat ⍝ Identity" ] }, { "cell_type": "markdown", "id": "da77be8f", "metadata": {}, "source": [ "#### Dyadic `⌹` (Matrix Division By)" ] }, { "cell_type": "code", "execution_count": null, "id": "04795293", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
┌→─────┐\n", "│¯4 4.5│\n", "└~─────┘\n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "⎕←div←5 6 ⌹ mat" ] }, { "cell_type": "code", "execution_count": null, "id": "8f78bb2c", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
┌→──┐\n", "│5 6│\n", "└~──┘\n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "mat +.× div" ] }, { "cell_type": "markdown", "id": "88dc2b77", "metadata": {}, "source": [ "## Custom operators" ] }, { "cell_type": "code", "execution_count": null, "id": "034e07cf", "metadata": {}, "outputs": [], "source": [ "f ← *∘2" ] }, { "cell_type": "code", "execution_count": null, "id": "12b4ae31", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "6.01\n", " \n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "d ← 0.01\n", "x ← 3\n", "((f (x+d)) - f x) ÷ d" ] }, { "cell_type": "code", "execution_count": null, "id": "a03eb5d9", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "6.0001\n", " \n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "d ← 0.0001\n", "((f (x+d)) - f x) ÷ d" ] }, { "cell_type": "code", "execution_count": null, "id": "701f4ec2", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "6.01\n", " \n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "grad ← {((⍺⍺ ⍺+⍵) - ⍺⍺ ⍺) ÷ ⍵}\n", "3 f grad 0.01" ] }, { "cell_type": "markdown", "id": "e871a76b", "metadata": {}, "source": [ "## Diaeresis and Tilde Diaeresis" ] }, { "cell_type": "markdown", "id": "f209adf1", "metadata": {}, "source": [ "### `⍨` (Tilde Diaeresis)" ] }, { "cell_type": "markdown", "id": "3e097c27", "metadata": {}, "source": [ "#### dyadic `⍨` (Commute)" ] }, { "cell_type": "markdown", "id": "ea9112b0-0901-4e8d-a081-3e51f399bc98", "metadata": {}, "source": [ "Modifies the given function so its arguments are swapped." ] }, { "cell_type": "code", "execution_count": null, "id": "cabed390", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "1\n", " \n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "3-2" ] }, { "cell_type": "code", "execution_count": null, "id": "c5b94832", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "¯1\n", " \n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "2-3" ] }, { "cell_type": "code", "execution_count": null, "id": "da470b37", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "¯1\n", " \n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "3-⍨2" ] }, { "cell_type": "markdown", "id": "7783d49c-2503-4639-a6bf-79c1146d812e", "metadata": {}, "source": [ "Normally to use a mask to select elements the mask is the ⍺ argument to /. If we wanted to right this out we would need to calculate the mask first.\n", "\n", "(≠v)/v" ] }, { "cell_type": "code", "execution_count": null, "id": "17cfef7d", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
┌→─────────┐\n", "│22 10 21 5│\n", "└~─────────┘\n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "v←22 10 22 22 21 10 5 10\n", "v/⍨≠v" ] }, { "cell_type": "code", "execution_count": null, "id": "f0bc56b3", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "6.01\n", " \n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "grad ← {⍵ ÷⍨ (⍺⍺ ⍺+⍵) - ⍺⍺ ⍺}\n", "3 f grad 0.01" ] }, { "cell_type": "markdown", "id": "c522a81a-f038-4403-8b24-2153ee0a24ad", "metadata": {}, "source": [ "Can also be used to reflect the ⍵ argument to become the ⍺ argument as well.\n", "\n", "3 × 3" ] }, { "cell_type": "code", "execution_count": null, "id": "7569f72e", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "9\n", " \n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "pow ← ×⍨\n", "pow 3" ] }, { "cell_type": "markdown", "id": "de3a07f5", "metadata": {}, "source": [ "#### dyadic `⍨` (Constant)" ] }, { "cell_type": "code", "execution_count": null, "id": "396b95e8", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "0\n", " \n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "zero ← 0⍨\n", "2 zero 5" ] }, { "cell_type": "markdown", "id": "8eea99a0", "metadata": {}, "source": [ "### `¨` (Diaresis)" ] }, { "cell_type": "markdown", "id": "35482065", "metadata": {}, "source": [ "#### monadic `¨` (Each)" ] }, { "cell_type": "code", "execution_count": null, "id": "65e7b966", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
┌→──────────────────┐\n", "│ ┌→──────┐ ┌→────┐ │\n", "│ │1 2 3 4│ │5 6 7│ │\n", "│ └~──────┘ └~────┘ │\n", "└∊──────────────────┘\n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "⎕ ← a ← (1 2 3 4)(5 6 7)" ] }, { "cell_type": "markdown", "id": "990a53df-822a-4cd4-870e-6912d8a3f81a", "metadata": {}, "source": [ "Apply +/ to each of the elements of a. Each element is itself an array. So we sum those up." ] }, { "cell_type": "code", "execution_count": null, "id": "fee3843a", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
┌→────┐\n", "│10 18│\n", "└~────┘\n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "+/¨a" ] }, { "cell_type": "code", "execution_count": null, "id": "c2f8b0be", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
┌→────────────────┐\n", "│ ┌→────┐ ┌→────┐ │\n", "│ │1 2 3│ │4 5 6│ │\n", "│ └~────┘ └~────┘ │\n", "└∊────────────────┘\n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "⎕ ← b ← (1 2 3)(4 5 6)" ] }, { "cell_type": "markdown", "id": "aa8b86d3-bf4b-41f0-924b-376596067525", "metadata": {}, "source": [ "Distribute the plus and an element to each of the elements of b. \n", "\n", "2 + 1 2 3 \n", "\n", "3 + 4 5 6" ] }, { "cell_type": "code", "execution_count": null, "id": "1f256e34", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
┌→────────────────┐\n", "│ ┌→────┐ ┌→────┐ │\n", "│ │3 4 5│ │7 8 9│ │\n", "│ └~────┘ └~────┘ │\n", "└∊────────────────┘\n", "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "2 3 +¨ b" ] } ], "metadata": { "kernelspec": { "display_name": "Dyalog APL", "language": "apl", "name": "dyalog-kernel" } }, "nbformat": 4, "nbformat_minor": 5 }