Fast.ai APL study session 7

Discussion of the 7th study group can go here. Overview

This is a wiki post - feel free to edit to add links from the lesson or other useful info.

Study session resources

2 Likes

Jeremy

I am having to watch these after recording and the quality is not clear at fullscreen. Is there a quality setting you can boost for recording?

Cheers

It’s recorded and available on youtube at 1440p.

Must be something my end - I only get 360p as option.

I was too keen - only low quality available immediately but 1440 available now

After todays session I was inspried to make some functions of my own. I created an APL version of Leibniz’s formula for \pi

\pi = 4 \left( \frac{1}{1}-{\frac {1}{3}}+{\frac {1}{5}}-{\frac {1}{7}}+{\frac {1}{9}}-\cdots \right)=4\left(\sum _{n=0}^{\infty }{\frac {(-1)^{n}}{2n+1}} \right)
⎕IO←0
pi_approx ← {4 × +/ (¯1*⍳⍵) ÷ (1 + 2×⍳⍵)}
pi_approx 1000
3.14059


Pretty good! The correspondence between the APL code and the mathematical notation is almost one-to-one. I am having fun turning math into APL

5 Likes

Since APL’s reduction is defined as insertion of a function between the elements of a vector followed by normal execution as APL (i.e. right-to-left), subtraction-reduction becomes alternating sum: -/a b c da-b-c-da-(b-(c-d))a+(-b)+c+(-d)

This means you can write pi_approx ← {4 × -/ ÷ 1 + 2×⍳⍵}

3 Likes

How do you define a shy result in a function?

Since assignments are shy, simply make your function end with an assignment: ShyPlus←{result←⍺+⍵}

f¨ always applies to individual elements, much like + does.

To add each number from 1 2 3 to the individual rows of a matrix, you can split the matrix into a vector of vectors, then do the addition, and then mix the vector of vectors back into a matrix: ↑1 2 3 + ↓matrix

However, much better is to master the Rank Operator so you can specify that you want each scalar (element; rank-0 array) on the left paired up with each vector (row; rank-1 array) on the right: ⍤0 1 — and thus 1 2 3(+⍤0 1)matrix

3 Likes

I think you have a systematic problem of terminology in the notebook document. While for functions, distinguishing between monadic and dyadic is enough, this isn’t the case for operators. There are indeed two types of operators monadic and dyadic, but each of these can in turn derive a monadic or dyadic (or ambivalent!) function.

For example, when looking at ∘ you have “dyadic ∘ (Bind)” where “dyadic” refers to ∘ taking two operands, because you’re using the derived function *∘2 monadically. However, for ⍨ you have “dyadic ⍨ (commute)” where “dyadic” refers to the derived function -⍨ being applied dyadically, while ⍨ itself is a monadic operator (taking only one operand).

This leads you to miss the fact that the monadic operator ⍨ also derives a monadic function even when the operand is a function. Confusingly, both when deriving monadic and dyadic functions from ⍨ with a function operand, is ⍨ called “Commute”. I personally prefer calling the form deriving a dyadic function “swap” (as in swapping arguments) and the form deriving a monadic function “self” (as in applying an argument with itself).

Useful examples of “self” are ×⍨ for squaring and +⍨ for doubling.

4 Likes

Many thanks - we’ll endeavor to fix that in our next session.

At [30:44] the question is asked how to define a shy result.

This cell prints out the result…

f ← *∘2
f 3


And this one doesn’t…

f ← { ff ← *∘2 }
f 3


[EDIT:] Shy is demonstrated at [41:55].

While this f is indeed shy, it doesn’t compute the square of its argument. It assigns the squaring function to ff and then doesn’t return that unless the value is used, but dfns are not allowed to return functions, so we get a SYNTAX ERROR. To make a proper shy square function, do:

f ← { result ← ⍵*2 }


Now f 3 will be silent, but ⎕←f 3 or ⊢f 3 till show 9. (The only important thing is that the function ends on an assignment; the variable name used is immaterial.)

We can even create a “make shy” operator:

      shy←{⍺←⊢ ⋄ r←⍺ ⍺⍺ ⍵}
2+shy 3
⊢2+shy 3
5


By the way, shy functions are very useful when the primary purpose of the function is its side effect, e.g. writing to a file.

3 Likes