 In this video we are going to review the basics of algebraic coding theory that we explored previously in Math 42 20. Now, if you've been following along with this lecture series, then it's been a long time since we've done anything with codes. So it's a good chance you've forgotten these things. Or if you're just new to this topic, you might need to go back and review some of these topics that we explored in our first coverage of algebraic coding theory. You should be able to see the links appear on the screen if you want to see those lectures for an in-depth review. Now, many of us, like I said, if you've been following along with the lecture series, then you might just need a quick reminder of many of these topics. And that's what I want to provide to us in this video. If this video feels insufficient, please go back to the original lectures for review. But I hope this brief video will be sufficient. So before we go into the details of the review, why are we coming back to coding theory? What's to be gained now? Well, you will recall, hopefully, at least by the end of this video you will, you will recall that when we talked about algebraic codes, we were really focused on this idea of a group code, which will define exactly what that is in just a second. But we can use the benefits of groups to help us study these error-correcting, error-detecting codes. But honestly, the types of group codes we developed were not the full-blown group theory. We really were focused on something called a linear code, which again we'll define what that is in just a second, for which in particular, these are vector spaces. All of this was taking place with linear algebra in the background. Linear algebra mod 2, mind you, but we're still doing linear algebra, so we use matrices and vectors in that situation. The whole point of a group code is like, oh yeah, if our code happens to also be a group, in that case it always led to a subspace, we can use algebra to strengthen our coding theory. Now, as we're trying to develop the idea of a polynomial code, we can make not just, we don't just have vector spaces anymore, we're going to come up with rings. Like after all, a finite field, every finite field is a vector space over its prime field. So if we take fields, finite fields of characteristic 2, in addition to a vector structure, we also have a ring structure. If the group structure of a vector space helped us make codes, could the ring structure also be beneficial? The answer is yes, and that's what we're going to return to codes to do, is to actually use ring theory, or field theory, finite fields to help us better understand codes, make better, better codes here. All right, so with that said, what are the basis of coding theory? So the idea was we have some type of communication. We're thinking of this as a digital communication, right, where we're sending sequences of zeros and ones. We could generalize this to other characteristics, but we're just going to focus on binary messages. So we have some binary messages that we want to send. Now that binary message is going to consist of m bits. The bit here, of course, is just a single character in this binary language. It's a zero or one. So m bit messages, we will just, I mean, that's just, it's the fundamental data thing we're trying to send there. We have a sequence of zeros, ones, and that sequence is m characters long. Now every binary m bit message, we can identify with a vector in z2m. This is the finite vector space there. So we want to transmit these m bit binary messages, but because there's noise in the system, we're afraid that error might enter into our message as it's transmitted. But it's important that our message be transmitted correctly, because otherwise the wrong transmission is like, do we make peace or do we send the nukes? You know, that's, you don't want to make that difference in transmission there. That's a big difference there. So we encode our message into an n bit binary message, for which we can identify those n bit messages with vectors in z2n. And so an nm block code called c consists of a couple things. We have an encoding map. The encoding map is a function from z2m to z2n, for which we are going to add extra information, in which case there's also a decoding map, which the decoding map is a map from z2n to z2m, right? For which the composition, if you encode it, then you decode it. This gives you back the original message. It's the identity on that situation. Okay. Now, of course, when it comes to transmission, there's often this symmetric binary channel that sits in the middle, for which t is a random function. It's going to chain some of the bits randomly based upon chaos and noise, in which case we would love it when this composition is the identity. We can't have that in general, but if there's not too many errors, we can error correct it so that it is the identity when the number of errors is one or two or whatever. But then there are situations which, even if we can't correct it, we can still detect and request a retransmission. In particular, the set C, the code itself, is the image of z2m under this encoding process. So we previously showed that the efficacy of decoding, excuse me, the efficacy of detecting and correcting codes happens, it has to do with how sparse the code words are from each other. Because if we have these two code words, one, one, zero, one, and this code word, one, one, zero, zero, right, notice that the difference between these code words, the hamming difference that is, is going to be one. If you change that last bit from a zero to the one, you go from one code word to another code word. So the distance, we'll call this one u, this one v right here, the hamming distance between these two words is going to be one. We measure how many differences are there in bits. There's only one difference of bit. And so because of that, if there was, if you wanted to send the message u, but because of noise, the last bit translated to zero, you then receive the code word v, and you wouldn't know that's an error because v is a legitimate code word. But if you make the distance between the words a lot bigger, so let's say you had something like zero, one, zero, zero, one, this is u, right? And then v, we take something to be like zero, one, one, zero. In this situation, notice the distance between these words is now four, okay? And so now if there's an error in transmission, you change that last bit. So we actually receive one, zero, zero, zero, right? You're not going to think that word was v because it's like, oh, that's too far away from v. It's probably u was the original message because that's the closest code word to that one. So a sparsity between code words gave us the efficacy of error detection and error correction. We wanted our words to be far apart. And this then depended upon what this quantity we called the minimum distance. What was the shortest distance between two code words with respect to the Hamid metric? The Hamid metric, which like we did a moment ago, measures how many different bits are there between the two code words, okay? And so what we proved previously when we first talked about algebraic coding theory is that if the minimum distance in a block code was equal to n, that means we can correctly detect up to n minus one errors. And the reason was for that is that every time there's a bit error, you have your code word, you change it a bit. You change it a bit. You change it a bit. You change it a bit. You change it a bit. If the two closest words are n bits apart, if you have only n minus one errors, you could not have gone from u to v. So you're not equal to v, so you don't think that's the code word. You're not equal to u, but you're also not equal to any other code word because there's no other code words that are close enough to u. Therefore, you know you don't have a code word so there was an error. An error was detected. Now, you might not be able to know what the correct word was because in this case, since there are so many errors, it's potentially closer to a wrong word than it was closer to the right word. That's a possibility, but you can detect errors. On the other hand, if you have, we'll put u and v back here, there's n difference between them. If you only go half of the way, n minus one over two, and you have to round that thing down because n minus one might be odd. But if you only go half, if you don't go more than half the distance in errors, then the idea is you can correct it by rounding to the closest code words. If there's not too many errors, I can then change that to the closest code word and that was then how you correct it. The minimum distance was a big deal. It told us exactly how good our level of detection was, how our level of correction was. Let's get back to the idea of a group code because we can identify c with a subset of z2m. In particular, if that set c is a subspace of z2m, we get what we call a group code because the subspace has an additive group structure to it. There is scalar multiplication, but when you're working mod two, the only scalars are zero and one. Scalar multiplication is not doing anything, really, it's not. So you're going to be a subspace of z2m if you're closed under addition and you're not empty. So that gives you a subgroup of the additive structure. We discovered that for a group code, the minimum distance was equivalent to the minimum length of a non-zero word. So we replaced minimum distance, in fact, with minimum weight. Although we typically still call it dmin in that situation. All you had to do was look at the minimum length of any word, which is, of course, the hamming norm in that situation. How many ones are in that binary sequence? We do exclude zero in that situation. So that fundamentally empowered our codes that it was so much easier to work with a code when there was an algebraic structure to it. So then we quickly shifted from group codes to the idea of a linear code. A linear code was defined to be the null space of a matrix. So your code c is equal to the null space of some matrix h. Which, remember, by definition, this is the set of all vectors, x, that belong to z2n, such that hx is equal to the zero vector, like so. So a linear code was then the null space of a matrix. So if you give me the matrix, then you have the code. One matrix encodes all of the code words, which was pretty nice in that regard. Now, how do you compute the null space? Well, you can solve the homogeneous linear system hx equals zero. That's not so bad from an algorithmic point of view. But if you have a generator matrix, that is some matrix which, when multiplied by h on the left gives you zero, then it turns out that your generator matrix g will have the formula. You have some vectors w1, w2, all the way up to like wk, something like this. And then we're gonna see that because hg equals zero, if we take the span of these vectors, w1, w2, all the way up to wn, excuse me, wk, this will then give you the null space of h. That is the columns of g form a spanning set for your linear code. So every code that can be produced as a linear combination of these columns. And if you choose h and g well, then you can actually guarantee that g's columns form a basis for the null space of h. And we can also compute efficacy very, very quickly. So our main tool was to use the so-called canonical parity check matrix where a, excuse me, the matrix a was formed in the appropriate, in the following way. You have some matrix a, you augment that with the appropriately sized identity matrix. And then g was then defined to be the appropriately sized identity matrix augmented with a. Now these identities are not necessarily the same size. They can be different for h and g, but we do have now that h times g is going to equal a times i plus i times a. This is gonna give you a plus a. And as you're working mod two, this will give you the zero matrix. And therefore that gives us exactly one. So that was a really nice scheme we had here. And then we could infer the efficacy of the code by looking at the matrix a. If there were no columns of zero inside of a, you could detect an error. If you had no repeated columns in a, plus no zero columns, then you could correct an error. Which means you could detect two errors. Because in those cases, the minimum distance would be two and three respectively for those two situations. So that was the basic scheme that we had developed beforehand. We also had the decoding process. So let's say that there was, let's say that there's a message w that needs to be transmitted. So this is something that belongs into z to m. So what we do is we transform w into gw. That then gives you the code word. And that's then the encoding process. We then send that through the binary channel, the binary symmetric channel. Some noise might have been created. And let's say that the message x is then received. X could be gw or it could be something a little bit else. So then the thing is if this does have the form gw, then of course h gw is equal to zero. So we then compute what is the so-called syndrome here. So we compute h x. Like so we compute this so-called syndrome. Okay. If the syndrome turned out to be zero, then that means we had transmitted the message correctly. And then we can peel away the check bits. We just have the information bits. And so then we can decode this. We can decode this and get back the original message w. For this matrix a here, it usually had to do with the shaving off some of the bits. And then you have that. If your syndrome, of course, was not zero, then there were some efforts we could make to correct it. This idea of coset correction. But we'll get to, we'll get to more of that in the future. But I want to review all of this idea of our linear code that we had developed in math 4220. And so in the next video for our lecture series, particularly in lecture 31, we're going to dive deep into this idea of a polynomial code starting with the idea of a cyclic code. And so I wanted to take the end of lecture 30 as an opportunity for the student here to review the details of linear codes if they think is necessary. This video hopefully is enough so that when you're ready to get started with cyclic codes in lecture 31, in which case I would invite you just to go start working on lecture 31 right now. If you start 31 and feel that this video was insufficient, you feel a little bit overwhelmed, then please go back to those references you saw in the links to this video to get a more in-depth coverage of those linear codes we had talked about in math 4220.