Back to Index

Fast.ai APL study session 13


Transcript

The site, but if anybody has any resources for signal processing in APL, I'd be interested. I did a quick search, but I didn't do an exhaustive one. So, like I said, I'll put something up on the site. But feel free to add something in the chat if anybody knows anything.

Thanks. >> It might be worth searching for the kind of things you would use for signal processing, like look on APL Wiki and stuff like Fourier transform or Kalman filter. >> Yeah, true. >> Evolution. Interesting to hear what you find anyway. >> Yeah, thank you. >> Okay, so I remember we were up to auditioned in close.

>> Has anybody skipped ahead to figure out what that is? >> It's not me. >> What button do we press for in close again? Let's see. Sorry. >> Oh, so for me, it seems like it was doing, say, if on the left-hand side you have 1, 2, 3, it would enclose the first one one time at like three elements on each side, 1, 2, 3 on each side.

>> Well, could you explain maybe the version we've got here? Does this make sense? We've got 0101 enclosed 1234. >> Oh, yeah, sure. I mean 0101, let me make sure it does what I think it does. >> So it's giving us 23 in the first cell and four in the second cell.

>> Apparently. >> It is. >> Okay, that is my understanding was wrong. >> Okay, all right. All the more interesting. >> Oh, well, okay. Yeah, I played with it a bit and thought I knew what it did. >> I'm getting a sense of what it is. It's looked like the ones are defining groups.

So it's taking where the first one is and giving us the numbers there, the letters in this case, then the second group is defined here, the letters there. >> Yeah, did you look on the APL Wiki? >> I haven't done anything at all. This is the first time I've- >> Okay, I was just looking it up in the background and I think it's starting to explain basically what you were saying.

>> Didn't they? >> It looked like it was a pretty good definition at least starting out. >> That second paragraph, oh. >> Yeah, it indicates where divisions begin. Cool, it seems pretty straightforward. So each one is the start of a new division. The APL Wiki example's a bit clearer, I think.

>> Or at least that one is. >> Yeah, that's what I mean, this one. Okay, so then they're saying some dialects by which I assume they mean dialogues included. Okay, so that's just saying create two partitions, make this the second. Have two partitions after the first and then three partitions after that.

So it's just creating some empty partitions. All right, well, that seems straightforward enough. Sorry, keep moving along then. Looks like the next one is left shoe underbar. Which is written as shift C, I guess, right, shift C, okay. Starting to get the hang of this. Oops. On edit, left shoe underbar means nest.

Let's check API Wiki as well, shall we? >> It's like- >> Yep. >> It has some, it's kind of like enclosed with some extra logic so that it doesn't nest too many times. If you nest and nest and nest, it doesn't do that. >> Okay, let's have a look at this example, shall we?

So this is, that's H, isn't it? And I think this means, is it an element of? And so this adds up how many times an A appears in each word? Okay, it's counting out the words, no worries. But if the user only gives one word, it'll count the A's in each letter because it's going H, yes.

You can apply nest, Okay, so, They've got some examples. I quite like that they're saying like an example of why it would be useful in API Wiki. Even if the examples are a bit complicated. Now that's the same as normal and close, right? And we can check that. By using the tally thing.

No, the other thing match. Okay, they're the same. Is this one different? No, this is different. Okay, I see. So what's the rule it's using? If y is simple, what does simple mean? I think simple means that it's an array that doesn't contain any arrays. So I think if we did two, three, reshape, iota six, that's the same because this is simple.

I don't know, I didn't type down where I got the definition, but a simple array is an array of depth one with all primitive values such as a string or array of numbers. Oh, perfect. By the way, what happened to our thing that shows like the little squiggle or thing that tells us, you know, the end shows us that it'll arrows.

Is that some different kind of boxing? Oh, we've got min, I don't want min, max. Okay, I think that tells us whether something's simple. Yes, okay. So if I do this, that's considered, so I think squiggle might mean simple. And this thing might mean not simple, maybe. All right, great.

So if it's just a, so basically if it's just an array, like, or tensor, I guess, then it's gonna return it unchanged. Oh, no, sorry, yes, I see. If it's an array, then it encloses it. Is that what it's saying? Yeah, that's it. Okay, so if it's an array, it encloses it.

Okay, so they're right, right, so that's enclosed. So if it's an array, it encloses it. Anything else, it does nothing at all. Okay, so they're the three possibilities, so I guess we should show them. And left shoe would have done the same thing, no? In fact, I just tried it on sleep.

In the example, it also worked. Right, a left shoe does the same in the case of an array, but not in the case of a scalar or a non-simple object. Oh, so sleep. So that's why you can see here, this is the same. But this is not the same.

As you can see, these are different. Okay. Okay, so in the case of a scalar, right, enclosed does nothing. Okay, so this is called nest. Okay, so they're exactly the same in the scalar case and the simple array case, but they're different in the nested array case. If it's already a nested array, it doesn't nest it anymore.

Great. So then, dyadic is partition rather than partitioned in close. Oh, I see. It's something about that the partitions are now defined in a different way, rather than ones and zeros. It's whenever the left argument. New division. Therefore, an element is greater than the nape and it's left. So here's a new spot.

Cool. Okay, and you can skip by setting a zero. Seems powerful. Okay, so by definition, You can split on spaces, for example. So here is a place where it's gone down and therefore it's gonna skip the fourth element, which is a space. And then this here goes up again, so it's gonna create a new partition, a new group.

Okay, so this is, I guess maybe a good time to talk about forks because their example here is a fork. So I guess let's start with, Does this example make sense to everybody? Does that make sense so far? >> It does make- >> Cool. >> It does make sense, but it seems like it's quite involved to what it can do.

And the differences between the operators that we've seen here on close. I'm just curious how much of this was in the original specification of APL, and how much of this evolved over time? So essentially, how much of this is coming from the CANI person's paper? It's just curious. >> Yeah, I assume this classic edition thing would be closer.

There is a APL dictionary on the J software website, which I guess would be a good place to answer that question. I thought, Maybe I'm wrong. Go to the API dictionary. Yeah, yeah, dictionary of APL. >> Wow, cool. >> Okay, so here's all the symbols, I guess. >> And the way- >> There's an enclose here.

Oh, except it's called superset. That's interesting. >> So the way he arrived on this was even without, before he, there was no implementation initially, right? It was just trying to find the notation. This was written in 1987. So this was well after there was an implementation. >> Right. >> Yeah, the original notation, I don't know what that kind of official.

Oh, all right, I guess going back here. Here we are, A programming language, 1962. So that was a point when there wasn't an implementation. >> Cool. >> And I think this would be interesting too, cuz this is where they actually designed IBM computer systems using APL as a notation.

>> Yeah, this sounds like a very interesting read. >> And this book I have. >> Thank you so much for sharing this. >> This book I have. >> What is it? Oh, it's its elementary functions? >> Yeah, it's basically a math textbook for designed at kind of high school level, if I remember correctly.

>> Let's see, one semester pre-calculus course, yeah. >> So he worked with the Fox Lane High School teachers. >> So yeah, it's like kind of normal stuff, circular functions, inverse, reciprocal, slope, exponential polynomials. >> But using- >> That is so cool. >> This notation. >> The environment or where this was devised and- >> Yeah.

>> The law of APL is- >> Although interestingly, he's got superscripts here. >> Which is not what we're using nowadays, we're using star. Although these reductions are the same, and he's got subscripts, that's also interesting. So anyways, so yeah, it starts off by talking about programming stuff, and then he's got a chapter about functions.

All right. >> This was fascinating. Thank you so much Jeremy for sharing this. Now I know where to look them up. >> Yeah, no worries. Yeah, the J software website, jsoftware.com/papers has, yeah, a lot of, they seem to spend a lot of time scanning in and even though CRing a lot of stuff.

>> I guess we can do the second example, can we? >> Yeah, so that's why I was saying we're gonna do forks next. Yeah. >> Same left, does that work? >> So that's a fork. Forks. Okay, so we've already talked about one fork. So the basic kind of idea that Adam said that maybe we can steal it directly.

So I'm not gonna do as good a job as he did. Where did he mention forks? Oh, maybe it was after the last study session. Yep. Okay, well, let's try his example. So maybe, If we could do The reciprocal of three plus e to the power of three. And so here we've got f plus g where f is reciprocal and g is exp.

And then we're adding them together. And so according to his example, that should be the same as that, which it is. Does that make sense? So first applies this to three, then it applies this to three, and then it applies this to the results. So the example we saw a little earlier was The very famous definition of the main, which is the sum divided by the count.

So here's a function. >> I think we might be in the situation where we cannot see the- >> Sorry, how's that? >> Yeah, that's perfect. >> There's a function, there's a function, there's a function. So make sure you put this operator with the function on its left. Plus slash, there's the middle function, there's the right hand.

So that's f, that's g, and that's what we're using instead of plus, using divide. So the sum divided by the count. So that is equal to two plus five plus eight plus nine divided by four. Does that make sense? So plus slash of 2589 divided by tally of 2589.

And so something that's very interesting about this is that if we defined a function, and this is something that Aaron Shue talks about in his ArrayCast interview, we could define a function called mean. And that's how we would define it, right? And we could run it. And so the interesting point though is that the word mean has the same number of characters as its definition.

So why define a function for this, rather than just use the definition anytime you want to use it, because that way you're being more explicit. That's a very good way to spell mean, because it actually tells you exactly how to do it. So it's a totally different way of thinking about software engineering is, yeah, not to create abstractions when you end up with an interaction where the number of letters in its name is the same as the number of characters in its definition.

So I think that's interesting. So here's another interesting example. Okay, so before we do it, we need this one. So, So this one, which is a little thing pointing rightward, there's that, yeah, okay, backslash. Okay, this is called right tack, which makes sense. It does look like a tack pointing right.

Right tack. And monadic is called same, and it's what we would normally call the identity function. And it just returns whatever it's passed. Okay, not much we can say about that, right? Diatic is called right, and it always returns its right argument. Okay, and I am pretty sure that left tack will do the exact opposite.

Except monadic will be the same. So left tack, This vertical bar makes sense. Starting to get the hang of the mnemonics for the letters now. Generally you shift to get the kind of the other version of the same thing. Okay. Oops, I forgot to change this. Okay, that's pretty straightforward, yeah.

So this next one is a fork. Which, okay, this one here might help to see each bit separately first maybe. Oh, this is a dyadic fork. I think a dyadic fork. I'm pretty sure, yes. Or a dyadic fork. H of f, oops, f and j past the left hand side and the right hand side.

So this one's pretty straightforward. That's just gonna return the right hand side. So we can then combine those together. To say. Left hand side. And then the enclose. Then the right hand side, which I don't have to put in parentheses, but I'm just going to. Okay, now look, these are the same, right?

Because this fork means that the left hand side and the right hand side are passed to this. And they're passed to this. And then this takes the two results. So this fork is something that will separate the string by spaces. And again, you could, well, not just by spaces, but by whatever's on the left.

So we could create a function for that called split. But the name of the function will actually be more characters than the three characters it takes to define it. Does that make sense? Wouldn't it be more readable to use alpha and omega in such cases? This is very cryptic.

I mean, everything's cryptic when you don't know it, right? I mean, if you do any work with math notation, in math notation, it's very cryptic. So yeah, sure, it's very cryptic when you don't know it. I think it's error than alpha and omega once you know, because there's less to, at least for me, less to keep in my head.

So the alpha and omega version, if you didn't want to do a fork, would be. >> You're replacing the space. >> Split would be defined as. >> Yeah. >> Alpha not equal to omega. Alpha omega, oops. >> You essentially have to do this in your head, if you want to, if I, right?

I mean, kind of, like, yeah, same thing. I think once you get comfortable with abstractions, you kind of don't. Like, it just slots in there. I feel like this version, you have to do it in your head. For this version, I think you could read it as, like, fairly directly in English as, what's this name of this character, dyadic, I don't quite remember, whatever it is, match, or whatever.

So it'd be like, you know, you could say, like, I should actually say the right words. Oops. Unique mask. Okay, so if you say. Unique mask partitions, the right hand side. You know, I think that's probably something that one could become comfortable thinking about that directly. I can see that.

It reminds me of your surprise the other day when I mentioned, you know, my daughter found it to understand APL than the normal math notation. But, like, I think we're just kind of, like, reflecting our own years of studying, you know? I actually think, yeah, so, I don't know, like, I'm not an APL speaker by any means, so.

All right, I think that's super interesting anyway, it's fun. I think that's what's intriguing to me. Like, it's interesting research to kind of think about this alternative notation and what it might mean to be comfortable with it. And, you know, hopefully my daughter will teach me. That by doing it.

Okay, let's do these errors. I'm gonna do them before partition and stuff because I want to segue into fork. So, we're using forks and trains interchangeably, or trains are- >> So, trains are great questions. So, trains just refer to a bunch of functions next to each other with no other punctuation.

So, a train, you know, an example of a train would be the one that we did for the power operator. >> Yeah. >> Super fun, at least I thought so. This is a train. Now, this train, we had Function, operator, function, operator, function. So, it's different, right? So, I guess this is a function and then this is an operator and this is a function.

I think you'd still call that a train. Another example of a train would be- >> We did a two train today. Did we do a two train today? When was that? >> Yeah, it was, I think, under dyadic partition. >> The one that you copied from, oh, here, line 31.

That's a two train, right? >> There's no train here. >> No, this is a three train, no? >> This is a three train, which is called a fork. >> Yes, that's why we're- >> Right, so you're looking for a two train. I just want to come up with an example of a two train.

So, a two train, for example, two trains are much easier to understand because they're exactly the same as beside or jot. So, if we did to the power of the reciprocal, we don't even need that, right? Then it's going to just, you just read right from it, one over three, e to the power of that.

Right, so that's the same as- >> No special rules, right? >> Yeah, no special rules. And in the dyadic case, then like that, then I believe it does three divided by three first, and then does e to the power of that. So, that's going to be e to the power of one.

>> Okay, that's interesting. >> And then this case is different, right? Because now it's treating it as this. So, that's going to be three to the power of the third, which will be the cube root of three. Now, in j, this means something else. This means something else, just to this way.

It would be the same as- >> Three on both sides. >> It would be the same as putting three on both sides. And that in j is called a hook. So, Adam's point is that we don't need a special thing for hook because we can always use- >> Until the- >> We can always use same.

We can put it there or we can put it on the other side to say, yeah, or you can use total diuresis. Yeah, okay. So, yeah, I think trains are just bunches of functions next to each other. Okay, so let's do the arrows, which I do see a lot.

So, it'd be nice to know what they mean. Presumably, they're going to call this up arrow. One would hook. Needs a space. Up arrow. How about that? All right, and it's called, oh gosh, what's this again? I think elk version is two, isn't it? One, okay. So, it's called mix.

Does anybody know why one would change this quad ML thing? I remember it refers to kind of like the version of the language or something. Mix or take. I like it. Maybe it's just for kind of compatibility. Mix. Mix hip hop. Okay, so. It looks like it's doing the opposite of that.

It seems to kind of go the opposite direction before, didn't we? From here to here. What's the rule? What's the rule of this rank of this? This one here. So, this is going to be, so the shape of this is going to be two, three. Where else the shape of this is two.

Yeah. Does anybody remember how to go from the matrix to the two enclosed versions? Wasn't that the left shoe? Let me try. This one? Destroyed, I don't know, I'm guessing. They're just wrap signals. No, that's not what you want. Right. We could do that with each, I guess. How about row to reshape?

That's not going to be the same thing because you want to actually enclose them. Oh, yeah, an H. Oh. What about the rank operator? Which one's the rank operator again? Is this one? Yes. Okay. I'm sure we had a better way than that. All right. So. It's going to look at what it's defined as.

An array whose items may be uniform in rank and shape or they might differ. Okay. Let's ignore the non-uniform case for a while. So then R is an array composed of the items of Y assembled into a higher rank array with one less level of nesting. Okay. That's exactly what we saw.

So we started out with a rank one array and we got a rank two array. And we have one less level of nesting. So the depth used to be true and I guess the depth is now one. If I remember the definition of depth correctly. If they have different ranks, each item is extended in rank to that of its greatest rank by padding with leading ones.

Oh, the rank is padded with relating ones. Okay. So for their example here. Yeah. So this is a vector. This is a scalar. This is a scalar. So this would get padded to become a one element vector. This would become a one element vector. So presumably if we did that manually.

We would get the same thing. And then y. Yep. That's the same thing. So that's what they're saying is being done implicitly. Okay, so if they're different ranks, you get the ones. Okay, then I got different shapes, which they do. So now each is padded with the corresponding prototype.

I think that a prototype is the kind of like base default value of a type. So for a number, the prototype is zero. I wish these kind of things had hyperlinks though to definitions. So that's why we ended up with zeros. So in other words, we could do the same thing by doing it manually.

So there's the same thing. Okay. So let's do the dyadic version, shall we? Oh, there we go. Yeah, so if anybody can figure out how to go from the matrix back to the array of arrays more conveniently than my ugly version, let me know. Oh, there's things in the chat.

You can do it by providing access to the shoe operator. Okay, great. Thanks, Vish. So although Adam's told us to kind of avoid access, but there we go. Hang on, I'm trying to go the other direction. I'm trying to start with the matrix. Oh yeah, which is what this has got it.

And then Molly's got an example. Okay, so what this is going to do is it's going to be a three by three matrix containing one, two, zero, three, zero, zero, four, five, six. And I don't think these parentheses are needed, are they Molly? Hey. Thank you. All right. Take.

Well, this looks nice and easy. In other languages, I think we'd call this head. Oh, or if you do negative, it's tail. I like that. I love that they don't create more functions than needed. Why not just use negative? Okay, so that just takes the first n characters or the last n characters.

Okay, so let's create a matrix. Of three by four of iota 12. And why do they go straight to the hard one? Let's just start with, okay, what if we do that? And let me print this out, shall we? What's the keyboard shortcut for quad? Here it is. Bar, vertical bar.

Wait, I'm confused. I thought that was, that's that. It's an L. Oh, it's an L. Thank you. All right, great. So this is going to grab the first two rows of the matrix. Cool. And this is the first two rows and the last three columns of the matrix. Okay, so here's a nice easy way to index into contiguous sections of an array.

Is everybody okay with that? So two minus three is going to be the first two rows, last three columns of this bit here. All right. Well, now I'm curious about what the other arrow is going to be. Oh, one other thing was taking more than the amount that was in the array.

Oh, thank you. Taking more than the amount in the array. So like five rows, for example. Okay, so I get spaces in the case. Oh, I think that's going to be called its prototype. And for the matrix, you're going to get zeros. Okay, again, the prototype. Cool. So yes, I think the space is the prototype for a character and zero is a prototype for a number.

Okay, is that all that? Have we missed anything else, Molly, or you think that's it? Um, well, in the case of, oh, here's an example that I wanted to share. Put it in chat very quick. Thanks. Because I found this behavior a bit odd. Sorry, not what I expected.

Okay, let's see what you got. Okay. All right, so you've got. So the the empty one. Oh, you're getting too many things. Wait, what? Okay, so it's it's repeating the first one. Yeah, the first one. With prototypes. Okay. Okay, I'm not going to leave this in here, because that sounds like a weird edge case that people can figure out, but that is interesting and surprising.

All right. How much battery have I got? Ten percent. Okay, shouldn't be too bad. Presumably, if I type down here, I'm going to get the down arrow. The down arrow does the thing that you wanted to do. Oh, all right. Yes, it does. Lovely. Great, let's deal now. Matrix then.

And it's year. How about that? Well, that's that's exactly as it should be. Okay. And you can also do it with an axis. Okay, and then drop. That's great. Everything except for. I wonder how close we are to finishing. There's still a lot of symbols we haven't done. I feel like we've done a lot.

Okay, everything except the first four. Now, what's this? Okay, makes sense. Everything except the last five. And it makes sense as well. Everything except the first two rows. And everything except those rows. Oh, well, actually, I'm not sure what this is going to do. Let's see if we can figure it out.

Everything except these is something of a weird shape. So what's going to happen? Oh, I see none of the top two rows. And none of the last three columns means you're left with this. So this is actually doing something. Yeah, a bit different. So we get rid of all those columns.

And we get rid of all these rows. And you're left with just the number nine. Okay, those sound like very useful things to know about. Anything else to chat about before we go? A productive day. Before the symbols, I will encourage other people to try to do the competition.

Serato, did you use the arrows much in your competition? A lot. A lot. Great. Yeah, I feel like I see them around. Sorry. Excuse me, but is the competition available again? You're very hard to hear, Radek. You're very... I think it should be better now. Oh, yes, that's much better.

Thank you. Sorry, sorry, switch to... So I'm wondering if the competition is back available again for this year, the 2022. I don't know, but based on the test case they show in the screen, you should be able to try working on it as well. Perfect. Yeah. But when you submit, you'll find out they actually have more edge case in the test, so you get your head around it.

I can always do it previously as one, as Serato mentioned before. And there are write-ups on the forums. They are awesome. So combining, trying to do the competition with looking at the forums after a couple of tries, that sounds like a really nice way of learning this stuff. I don't see a way to see the current year's ones, because it tells you...

Yeah, I don't see it on their webpage. It might be... Yeah, I might have to wait. But last time they have the PDF done, maybe I can post it. Yeah, please do, because I don't see it. Yeah, and then you can just space on the test case. That'd be great.

They only have four test cases, and then at least you have some time return to work on. Or alternatively, maybe post a notebook or something with the questions, but not the answers or something. I don't know. Yeah. Yeah. That'd be cool. Okay. Bye. Thanks. Bye, everybody. Have a good one.

Bye. - Okay. - Thanks. - Yep.