Back to Index

fast.ai APL study session 9


Transcript

>> Hello. >> >> Can you hear me? >> How about now? >> Good. >> All right. That weird thing where I just have to turn the volume up and down for no particular reason. >> I think sometimes there's a setting when you start, they turn off everything. >> Look, Ben's joining us.

Hello, Ben. You're muted. >> Hello. >> It's like you've got a halo around you there. >> Very elegant. >> I put it there especially. >> Nice to meet you. >> Hey, Serada, yeah, yeah, Serada and I live on the same side of the country. We should catch up sometime.

>> Oh, you're in Perth, Ben? >> I'm in Collie, which is 40 minutes up the hill from Bunbury. >> It's another two hours. >> It took two and Bunbury's two hours south of Perth. >> That is Bill Collie. >> C-O-L-L-I-E, like the dog. >> Collie, Western Australia. >> It's the power generation center of the state prior to renewables.

>> Okay. I see. You're inland. >> Yeah. >> Lots of forests around you. That sounds nice. >> It is, yeah. Yeah, actually, in my introduction at the course, at least I showed a few videos of the place. We were transitioning from coal powered to something else, so not quite sure yet.

But the government's putting a lot of money into the town to help it get started in other industries, so it's good. I don't know. Yeah, so usually, this is right in the middle of my drive to work. But I've got a little cough developing, so I thought I'd stay home and have an opportunity to tune in.

>> I hope you're all right. >> Yeah. Yeah, I'll say I guess. >> All right. Any news since yesterday? >> I was just looking at one thing that just happened to do a pull on the APL notebook. And I was just looking at the 911, which is monadic, and it's called rank.

>> Are you looking at what? >> I'm looking at the notebook. >> The notebook, yeah. All right. I got it open here. >> So I'll just go there to pull a few minutes ago. >> Yeah. >> So it should be 911. >> What does that mean, 911? >> They're auto-numbered, each thing.

>> I don't have numbering on one. >> No? Okay. It's interesting why mine's different. >> That's because you'll have the Table of Contents extension installed. >> Oh, gotcha. I can say dot diuresis. >> Okay. >> The monadic. >> Go down to operators. And -- >> Yeah. Towards the end.

>> Jot diuresis, yeah. >> Yeah. It says -- in brackets, it says rank. And that's -- what it's doing is not what I understood rank to be. >> No. That seems to be incorrect. So -- >> Jeremy, do you want to start this group? >> Yes. Just looking up the correct name for jot diuresis.

>> Oh. It does say rank on -- >> For a different meaning of rank, is it? >> Yeah. Yeah. Okay. No, it is -- oh, yeah. It is rank. And we haven't really fully investigated this one yet. So, yeah. Let's come back to that. Maybe even today. All right.

Let me share my screen. Hi, Wasim. How are you? >> I'm good. Thanks. >> Not bad. All right. So, yesterday, we were doing access. We did comma. We did comma bar. Was that basically where we got to? >> Yes. >> Yes. >> Okay. All right. So, yesterday, we were doing access.

We did comma. We did comma bar. Is that basically where we got to? I guess so. Oh, and then we were doing access with monadic operand. Okay. Yeah. Well, that's actually not a bad time, actually, to look at jut diuresis. So, what if we move -- well, I mean, the first thing I'd say is slope.

And slope probably deserved to be moved up anyway. And then let's move jut diuresis up. Okay. And then this one -- oh, okay. This one's got a monadic as well. Sorry. No. Not a monadic as well. Okay. This is where we need to be careful to include the -- all the possible versions.

So, there's both rank and the top. >> So, rank is not its meaning. >> Rank is its meaning. >> This is the type of -- >> Rank is its meaning. Yep. I don't know what it is now. It is the rank operator. So, okay. So, it's quite similar to axis.

And in fact -- okay. So, slope bar and slash bar are basically identical, I think, to using the axis operator. Yes. As you can see. And then rank is also the same. Yes. As you see here. So, the rank operator is -- takes a function on the left and a scalar on the right.

Is it always a scalar? Wrong one. Okay. It can be a scalar. Sorry, a scalar. Or it can be a vector. Ah, yes, yes, yes. Okay. I knew that too. All right. So, what this is going to do is it's going to take the plus/function and it's going to apply it over this axis.

So, it's very similar to the axis operator. Just to clarify, it's not ranked in the way that we learned through the course, where it's the number of dimensions. Correct. It is not. So, it is not that. So, that rank is row, row. So, you can always get the rank by calling row, row, row.

Maybe just an extra comment there, just because when I read rank -- Yeah, I mean, I haven't added any pros to this yet. So, I'm not going to add it just yet, but yeah, when we do that. So, if we've got here -- so, the first dimension, the first axis is this one.

So, this is going to apply sum over the first axis, which is identical to /bar. No, it's not /bar. /bar would be doing it over the second axis. So, there's only -- okay, it's different to axes, because if we did axes -- I need to use a cube for an example to see the difference.

Okay, so axes work this way. It specifies the rank of the cells. Okay, so it selects k cells of the corresponding argument. So, k cells -- so, okay, so the one cells of this are the cells which are vectors. I see. So, rank isn't able to, like, transpose it or anything, I guess, using this approach.

I don't know if there's something -- if it's negative -- here we are -- if it's negative -- minus one selects major cells. Okay, so there's a whole thing about cells and subarrays here that's useful. A rank k cell describes a subarray on the last k axes, okay? Negative k describes a subarray on the leading k axes of an array.

R plus k. What does that mean? Because, like, r is the rank of the array. Okay, so in our case, that's two. So, a negative k would be -- oh, r plus minus one. I see. That's why. So, got it. r plus minus one would be the last axis.

Okay, that makes perfect sense. Yeah, so this is different to the axis operator. You can't change the axis. You can just say, what cells to do this over. So, I like this idea of using a cube. Okay, so that's doing it over the one cells. So, these are the one cells, and here are the sums of the one cells.

Okay, so then if we do two, it should be over the two cells, which are -- interesting. Two cells would be -- I thought a two cell would be this whole thing. So, I was expecting it to add that all up. Do they have some examples? Oh, my gosh, this is confusing.

I posted a link in the chat. Go ahead. I posted a link in the chat to the wiki, which shows strength versus axis, like some examples, how to get the same. Okay, forgetting to use APO Wiki. And what's an anomalous axis operator? The non-negative right upper-end, that's what we have, specifies the number of final axes to which the function applies.

Negative is complicated. That shouldn't make any difference, should it, when you've got a rank with it? I'll try it. I think this should be the same. Is the round brackets causing something to change how it's applied? The round brackets, I think, would be necessary, because otherwise, because of precedence, without it, it would be parsed like that, I believe.

Okay, so this is different somehow. Okay. Monadic. Okay, dyadic/bar as an operator. So the sense and subarrays documentation says that two cells are like two matrices of 2D shape. So if we look at the notebook. Just before we do, I just want to mention this, this is what I thought.

It says it just implies reduction among a particular axis. So I'm not sure why these two are giving slightly different answers. Oh, I see why. So cube is reducing down. So in this case, it's one cells are considered to go kind of downwards rather than acrosswards. That's why it's different here.

So it's doing matrices, and it's summing up each thing in each of those matrices. Okay, yeah, sorry, go ahead. So what are you saying about notebook? I think you are on the network. So the documentation says if X is the three dimensional matrix of shape 2, 3, 4, the two cells are two matrices of shape 3, 4.

So in our case, it is two matrices of shape 2 by 2, 1, 2, 3, 4, shall we? So 2, 3, 6, 4, so 24. Okay, yeah. And so two cells rank two cells are the matrices of shapes 3 by 4. And we are applying the slash to that whole matrix, each matrix.

So slash bar, I guess, is applying it to the last axis. So 1 plus 5 plus 9 is 15, 2, 6, 10 is 18, and 13, 17, 21 is 51. So the operator is applied for each matrix of 3 by 4. So normally, if we went matrix is a 3 by 4.

Yeah, so that is the first row of that because it is being applied to matrices. Is that the idea? And then this one is being applied to vectors. That one is the rank of the submatrix, the documentation we showed you before, k cells. Yeah, so that, I believe, is a k cell.

So I'd expect you to get 7, 10. Yes, which you do, 10. Okay, that makes sense, kind of. The one I think is particularly helpful is the version where you pass a two-element array on the right-hand side. Because then you've got, we should be able to add, let's say we wanted to add 1 to each row or add 1, 2, 3 to the first, second and third rows, we'd go 1, 2, 3.

Now, you can't just add that to the matrix because they don't match. But what you could do is you could say, so the keyboard shortcut for this is Shift + J. So we're going to go through each cell on the left, and then on the right, we're going to go through each vector on the right.

That is 0. Yes, okay, scalar on the left. So this is going to go through each scalar on the left and each vector on the right. And so the vectors on the right are the first one will be 1, 2, 3, 4, and the first scalar on the left is 1.

So the first result is 1 + 1, 2, 3, 4. The second is 2 + 5, 6, 7, 8. So that's how we can do quick loops between two different things. So that's a pretty important operator, and Adam mentioned that as well on the forums. Does anybody have any questions about that?

It's a bit odd. I think a key thing is to look at this idea about cells and salaries. I've come across this before because they talk about it in J a lot, J being the language that Iverson built after he built APL. All right, so maybe we should move to a top, which I think is going to be easy because I think it's largely the same as Jot, Bind, like so.

So we can just borrow the use from Jot. And this is not monadic. This is dyadic. So that should all be the same as far as I know. OK, I think so. Shift J. Oh, different. OK, let's find out why. So a top fgy equals f of g of y.

Oh, this is this is the wrong version. I need to bind one. No, I don't need to find what I mean. I need the side. Yes, it's the same. Oh, and this one is the same. It looks like for Jot we. Now that's interesting. There's some difference between them.

I thought in the dyadic. Oh, OK. I need to. OK, whoops, I forgot to change it. Oh, that's the same. And this one's different. OK, so the monadic one's the same, the dyadic one's different. Let's have a look. I think there's some nice pictures. OK, here's the difference. So beside, which is the one we've learnt before, first of all, applies the right hand function the way Adam describes it as a preprocessors, the right hand side.

And then the left hand function applies to the left hand side and that preprocessed right hand side. Oh, and a top's doing the opposite, basically. It's applying the right hand side dyadically and then post processing with the left hand side. You see the difference? OK, so that means that this one here would be should be two divided by three first.

Two divided by three first, and then it's going to do e to the power of that, which means we basically don't need any parentheses. Does that make sense? It did for me. All right, great. Thanks, Molly. Still getting my eye in with all the symbols. Yeah, tell me about it.

Eddie, in particular, you want to explain or reviewed? No, no, it's just just having the time to process. So this is this is either the power of so they say to the power of two thirds. Cool. Which makes me think we should do this last one now over. Probably makes sense, right?

So over is here, shift over a little bit confusing because it looks a bit the same. Just in those three diagrams, can you in the notebook, can you break down which is X and which is Y? So why is always the right hand side and X is always the far left hand side.

And you can tell in the documentation because if you look at a particular example, like here, over here, it shows you here. So R is the result, X is the left hand side, Y is the right hand side, and F and G and the left and right arguments to the operator.

Yeah, I just in the example, I just want to concretely point it, which is which. So in the example, this is X, this is X, Y, and G is inside the F. G is F and G. Yeah, got it. And if you define your own operator, they have different names.

I kind of wish I used these names in the documentation. They're called F is called Alpha Alpha. G is called Omega Omega, which we don't have for this one. X is called Alpha and Y is called Omega. So over is. Okay, same thing monetically. That's pretty easy. I guess we don't need quite so many examples for the ones that are identical.

Okay, so right. Paste that. Okay. Shift-O. Symbols called circle diuresis. And. Click version. That. Over. I should do this one. Over. Okay, so over. That should be exactly the same. It is now the. Dietic version is different. It's going to apply G. It's going to pre-post both left and right.

So I'm going to try to predict what it's going to do. So here. It's going to apply divide to both sides. So we're going to get. That. I think should be the answer. It is. So it's applying divide to the left. It's applying divide to the right. And that's applying power of to that result.

That is what this useful picture is showing. Okay, and then it's showing when any of these applied monadically the dotted branch disappears. It means in every case you're left with fgy fgy fgy. All right. It's nice to see all these different types of function composition. Yeah, you know, it's something that we're not used to from other languages.

Are we really. But the idea. Comes from combinatory logic. And there is the Haskell Haskell carry kind of, I don't know if you invented it, but he certainly developed it. There's the carry combinators. Very combinators. It basically defines these different ways of combining or I guess we'd say in computer science composing functions.

And so, yeah, all the all the these ways of doing things in APL, I believe, directly align with different carry combinators. I am not at all an expert on that, though. Is that where the term carry comes from? It is used in carrying of functions. That was a distinct predated Haskell Haskell is named after Haskell carry Haskell carry predates Haskell by a long way.

And that's what we would call partial functions in Python. Right. Another thing I wanted to mention, actually, which is to go back a bit to the Boolean stuff. I feel like we should have covered a couple of other things. One is, I think we should have covered slash as a function.

Because we've covered slash as an operator, but not slash as a function. And the reason I want to put it with Boolean is because, oh, in fact, there's quite a few monadic versions, like quite a few. Check this as equals. It doesn't have a monadic, not equals. Yeah. Okay.

So I want to do you guys remember monadic not equal to which tells you, have we seen this number before in the list? And so it's going to end up giving you a one for unique values. Where this is interesting is we can combine it with slash. Can you guys still hear me my headphones today?

It's good. Okay, I think they're running out of batteries. What should I do? I'm going to go a bit more fancy. Can you guys hear me? Yep, can do great. It's a bit louder, bit louder. Okay. But okay. Cool. See if I can adjust it here. All right. Yep.

All right. So paste. So we're going to do slash as a function. And it's called replicate. And what it does is it, let's put this in V and then not equal to this eight. What it does is repeats whatever's on the right by the number of things that's on the left.

So if we say on the left is a boolean array. And on the right is the array itself. And that returns a unique list of the elements of V because it's basically element wise repeat. So one copy of 22, one copy of 10, zero copies of 22, zero copies of 22.

Does that make sense? One copy of 21. And so that's the result. So you don't need a separate unique function in APL. You know, we can just combine this idea of replicate with unique mask and it behaves as a mask. Is is this where they might use that xy swap thing to get rid of the brackets?

Yeah, could try that added as a second line output to quarterly. Yeah, just oh, yeah, we could do that. Now. Let's do it all up. We'll see Daisy. Yeah, but it was a second line. Okay, so actually I have a general question for everyone. With the keyboards, I find that actually I actually I haven't tried to hunt this down myself much, but I find I'm hitting control and shift keys often to do things and it changes my keyboard every time.

And then my control Z's don't work. Does anyone else experiencing that? Yeah, so you can just hold down Windows and press space to switch. It does, but but it's also switching keyboards every time I hold control and shift together. Oh, you can change that in your language bar settings.

Okay, I'll go looking for it then. Cool. I'm on a Mac at the moment, so I don't see the same thing. Okay, so the swap was like this one. I think so. Shift T. So switch them around. And if we'd done that yet. Now we haven't done that yet.

I won't put it there, but yeah, that would totally. Totally work. And then yeah, the other thing you can do, since it's replicate. You could say like. So it's just going to repeat. Maybe we want to repeat the constants three times or something. There you go. I like this thing in APL, you know, this like, I feel like things are always just made more general than most other languages.

So rather than just having a Boolean mask operator units called replicate. I like that. Very cool. Yeah. Very cool. All right, so then we need to revisit all of our operators and make sure we didn't miss any examples of what they can do, which is what Adam pointed out that probably that we definitely have.

So we've got. Yes, we have not done expand, for example, which is, oh, that's used as a function. I've never seen this before. So in the, in the, in the letters, wherever it had the minus, it gave spaces. It's got one and then two spaces and then a sub array of fill elements is replicated.

In the matrix example, you've got a number one and then you've got two zeros because it's minus two. And then you've got two replicated. So that's replicating the second element twice, and then you have. Yes, it's doing it kind of like across columns. I think you put it in your local and had a box around it may be easier to see.

Oh, you think there's a boxing thing going on. Yeah. Yeah, I think the second one to ace that may be definitely have some boxing around it. Okay. Not much to say. I guess that means it's these actual spaces. That's two spaces. Yes. Okay, this isn't really got anything to do with Boolean so we can probably come back to it.

So I don't think we need that right now. As an operator. We've done. Okay, they don't. They got a dyadic. I don't think so. Okay, so I think we've done this operator. Carefully. Slash bars the same. And I think we check these pretty carefully. So let's check start I recess.

I recess power operator. Okay, I don't think we've. Oh, I did want to talk about power operators some more because we missed a really interesting case of power operator, which is a, a negative number here. So if you remember, here we're saying, okay, this is, sorry, this is the successor function okay so it adds one to things.

And this here says run the successor function three times to zero, so we get three. So what's interesting though, is we can also say, we can also create subtraction. And the way we can create subtraction is to say it like subtract one example subtract one. So, if we have a P predecessor and sort of successor predecessor, we can define as successor start I recess.

Oh, I'm notice. I don't know if it's only me but it looks like you're typing off the edge of the screen okay thanks let me know. I can see that. Yeah, I can see it now. All right. Power negative one. Now what power negative one does is it's the inverse function.

So the inverse of adding one is subtracting one. The predecessor of three should be two. Isn't that amazing. So, APL understands inverse functions, which is a pretty sophisticated mathematical concept, and it's even like doing inverse functions of functions that we have to find ourselves. And if you put a negative, something other than one, I believe it applies it.

The inverse function that many times. I think we could say, apply this successor inverse function three times to the number five, for example. There you go. The equivalent of five minus three. So you could also do a square root. If you wanted square root. You could do. So that's going to be, let's say square is to the power of.

So then we should be able to get the square root of nine by doing square. Inverses the inverse function of square. Which is square root. There you go. Cool, cool. Very cool. So it's like solving the equation, you know. Yeah, okay. So I'm glad we revisited that one. I think that's pretty amazing.

Children diuresis. Okay, yeah, we missed one of these. Diatic. Mute. Oh, no, it looks like we've got it here. And it's also. This one's called. This one's called constant. All right. Mute. All right. And then diuresis. Okay, each. And we've got each with. Okay, so now I'm wondering what does anybody remember on the forums, Adam said that there was a.

Problem. Without operators. And he had a particular example of something we missed. So I made this post. Oh, that's interesting. So Adam says many aplas. Brown on bracket access. As anomalous. And there's no general rule. The modern alternative is rank operator. Often together with transpose. Okay, we haven't done come to that yet, but I guess we can guess what that means, which is general call.

So you don't often need bracket access. That's good to know. So transpose should be one we could do reasonably early wouldn't rely on. Yeah, the other ones. Absolutely. I'm just trying to find this one with. About what we got to fix. I'm pretty sure we're missing something. Okay, systematic problem of terminology.

So for functions. Yes, they're monadic or diet. But for operators, there's monadic and diet operators and then these can derive monadic and diet functions. Well, this one we've got diet commute. So we've missed the fact that this drives a monadic function. Okay, let's check that one. This to order diuresis arrives and monadic function.

This is this here. Oh, look at that. If the left argument X is admitted and you can tell that you can, because it's in curly brackets here. And the right argument is duplicated. Okay, not sure the API docs really laid that out as nicely as Adam Adam is done either.

It's not really showing us that as clearly. Yeah, I can see that now. So we need to check when we look at the documentation for these X curly brackets to see things where there's a optional. Left hand side. That's interesting. So it's going to duplicate it. What would be an example of where you might want to do that.

I think maybe our unique thing. I think that work. So let's do it the other way around. V slash. Oh, I have a feeling this is going to work. V slash. Well, not quite. So we've got this. Which has got V on both sides. So I wonder, I don't feel that confident, but I wonder.

Let's do that. Oh, I've got it in the wrong place. The problem is that's going to put this on each side. All right, that's not a good example. Okay, so does anybody have an example of something? Oh, I know a simple example. We could define power as being multiply on either side.

That should be power, right? Ah, yeah. There you go. All right. Well, if anybody comes across any other ones where we didn't notice a monadic version, let me know. Just back in that previous cell, did you want to lose that previous example? Which previous example? The one you either wrote to in the cell 223.

Oh, was there something there? Oh, this one back in that cell. If you just hit controls it a few times, you'll see maybe maybe you meant to override it. But it was a look like it was a good example before that. This is you didn't want to keep that.

Oh, yeah, because we can use it. I see what you're saying. We can use it for the we can use it for this one. Just you just give it a new cell. Yeah, yeah, yeah, that makes sense. Okay, thanks for the idea. Okay. All right. Thanks, gang. Cheers. See ya.