Hey folks, welcome back for another episode of Code Club! If you have been following along in recent episodes, you know that I am building an R package in order to help me to learn how to make R packages. This is something that my lab is starting to do more of, trying to make packages in R so that people can use all the great things we've been talking about over the history of Code Club to better analyze microbial ecology data and other types of data. Anyway, I had to pick something to make a package for, and so what I picked was a algorithm called a naive Bayesian classifier. And so, again, even if you don't care about what the actual application is, like that doesn't just make you excited, like it makes me excited, I think you'll get a lot out of this series of episodes, specifically how to build a package, and kind of some of the differences between taking a data analysis approach to writing R versus doing a programmatic type of approach like we are when we're making a package. As I go through, I try to articulate some of the different design considerations and coding considerations that come to mind as I'm trying to build this out. In the last episode, we talked about taking a DNA sequence of ATs, GCs, and sometimes Ns, and converting that to base 3, so 0, 1, 2, 3, and that what that allows us to do is that when we pull out a k-mer, say a 8 number sequence, or a string that's got 8 numbers in it, that being an 8-mer, which is the default k-mer size for this algorithm, we can take that base 4 8-mer and actually convert it to an integer that's base 10. What that allows us to do is that allows us then to directly index into a vector or a matrix to the exact spot we want very efficiently. Alternatively, if we had kept things in kind of the character space, ATs, GCs, and Cs, then we know that there'd be like 65,000 plus possible 8-mers. And so if I had an 8-mer that I needed to look up, well, every time I go to look it up, it's like going through a phone book trying to find someone's name, right? That can be pretty tedious and pretty time consuming versus if I told you to jump ahead, 253 pages, bam, you'd get there instantly, right? So that's what we're trying to go for. Well, in today's episode, that's a long-winded way of saying for today's episode, what we're going to do is build upon that to then build a vector for each sequence that tells us whether or not that specific k-mer was present in our sequence. Then with that vector for an individual sequence, we'll then build it out for all of the sequences in our database. And from that then, we will then go and calculate the total number of sequences in each genus that have a specific k-mer. That will allow us to calculate the word-specific priors and the genus-specific conditional probabilities. The word-specific priors were described in this paragraph within the method section of this wonderful paper. It's here on page 2 in the first column if you like the analog version of the paper, like I do. Anyway, the expected likelihood estimate for determining the Jeffrey Perks law of succession, whatever that is, determined by the formula, pi equals nwi plus 0.5 divided by big n plus 1. Basically, what this means is that if we take all of the sequences in our dataset, we can count how many sequences have each k-mer. So that wi we can think of as being all possible eight-character sub-sequences or those words, nwi is the number of sequences that have that. We're only counting occurrence one time per sequence. So if a sequence has, say, a stretch of nine a's in a row, well then it's going to have that eight-mer of all a's twice, right? So we're only going to count that once though. So we're going to count the number of sequences that have a given k-mer, add half, and then divide by the total number of sequences plus one. That half and that one, what it's doing is say we have a k-mer that is really rare and say it doesn't actually show up in any of our sequences. Well, we don't want the probability to be zero. Instead, we want it to be a really small number. So in that case, the nwi would be zero and we'd get 0.5 divided by a big number, which is again a small probability. With this word specific prior, we'll then be able to calculate the genus specific conditional probabilities. And this is the probability that a member of a genus contains a specific word. And so in the algorithm that was calculated or estimated by this formula, again, it's the same idea except m, instead of looking across all sequences, is looking within a specific genus to see in that genus, say like Escherichiae or Pseudomonas, how many sequences have a specific k-mer. And then we're going to add the pi, which we saw in the previous slide for those priors, divided by the number of sequences in the genus plus one. So this pwi given g then will allow us to then calculate the probability of seeing a sequence from a specific genus as we see down here in this last sentence. Again, in the last couple of episodes, we've talked about collecting those eight nucleotide words. What we're going to do now is to move on in this reference column to calculate the pi, the prior for each word, and then to calculate that conditional probability for each word given a genus for each genus and word. So that's what we have to do today. And we'll head over to our studio and get going on that now. I already have my k-mers.r and test k-mers.r scripts open up. You'll notice I'm putting everything into these two files at some point, but not today. We're going to have to kind of take a step back and perhaps do a better job of organizing this because we don't want to have a package with one r script. That's probably not ideal. And of course, we are still at kind of the early stages of developing this package. Anyway, we'll worry about that later. So I'm going to come down and create a new test. So I'll do a test that. So the first thing I'm going to work on today is accurately detecting each k-mer for a given sequence. So I'll go ahead and do accurately detect k-mers from a sequence. All right. And then, again, hopefully we're getting used to this syntax for our test of that statements. So I'll go ahead and grab this sequence because it's already converted to base four. And so I'll call this sequence. So from this sequence, I'm going to get all possible k-mers. I'm going to use the function that I've already written and tested. So I'll have to get all k-mers on the sequence. And again, if I load everything here, and I can load things quickly by doing shift command L, and I can do shift command T to test, these are two keystrokes that I have started to use to allow me to do the loading and testing all the easier. So this will give us our sequence and then all possible k-mers. I'll go ahead and call this my k-mers. And then I'll have my indices, which will be base four to index on my k-mers. And that's not happy. Oh, because I haven't run this line. All right. So now I have my indices. And those are those indices. Cool. And so again, if I think about what I want to do here, is I want to get a vector for this sequence. So I'll call this detected. And my function is going to be detect k-mers on sequence. Right. And so this detected will be a vector that is four to the eight. So that's four to the eight units long. So 65,536 elements that detected will have. Right. And so what I expect then is that if I sum up the values of detected, again, those should be zeros and ones that I should get the sum of those ones should equal the length of indices. Right. And especially if I take detected an index in indices. Right. So if I take detected and then put in indices, this will return a vector with only those values. Right. And so I could then say something like the length of this, right. And I can do expect equal length of that. And then the expected would be length of indices. And another test I might do would be expect equal. Like I said, we could also kind of invert that. So we could do length. Actually, let me, let me actually copy this down. And I'm going to invert it. So everything that's not an index will show up. And then I'll have a length of that. So I could also then say like four to the eight minus the length of indices, which would tell me everything that wasn't detected. Right. So this is looking at what's detected. This is looking at what's not detected. I think I'll add another test based on this one where instead of length, I'll do some right. And so if these values are all ones, then summing them up should be the same as the length of the indices. Okay. So these are kind of three tests that I want to check out and go ahead and run the tests on that and find sure enough that it fails. It runs the first test and then bails out when it fails. So it's having a problem because it can't detect k-mers. I'll go ahead now and create that function. So over here, I'll do detect k-mers. And I'll do sequence. And I also want the default k-mer size. So I'll do k-mer size. By default will be eight. So again, I'm giving it the sequence. I'm not giving it the k-mers. Right. And so basically what I want then is this stuff. Right. And so I'm going to go ahead and copy these two lines. And so this is maybe cheating a little bit because I'm writing my code in my test. But I understand that there's some people that do test-driven development just that way. They write the test and get it to pass. And then they copy that code over into their function. So maybe along the way we'll make another test that's kind of independent of this code that I've written. All right. So again, we have k-mers and indices. And now I need a vector that is the total length of the number of k-mers. Right. And k-mers, I'll say four to the k-mer size. Right. And again, in the future, we might do seven, six, nine, 10. Who knows, we'd like to have that flexibility in the k-mer size. And again, I need for my development purposes here, I need to go ahead and load that in. And again, what we've seen before is that n-k-mers should be about 65,000. And so that's good. Right. So to create a vector, I could do numeric on n-k-mers. So this then gives me that vector with 65,536 entries. It only shows me the first thousand and kind of quickly scanning through these. We see that they're all zero. Right.  And I can then do k-mers detected. And I can then index into that my indices and say that equals one. So I'll go ahead and save that and let's test. So this is failing. And I think I know what is wrong. It's returning, it seems to be passing the first test for some reason. Right. So it seems to be passing this. I'm not really sure why. So, but it's failing the second and third test. I think the problem is that I'm not returning a number of k-mers detected. So I'll do return k-mers detected. And so our functions return the last calculated value. And so I think here it's returning one rather than k-mers detected. So I think it's good to always be explicit. You'll see up here I've got a function or a couple functions where I don't return, have a return statement. And I think in these cases it's more obvious because the output of the pipeline is the value. So let's go ahead save this and test and see what happens. So that all passed. So that is a good sign. So I want to go ahead and rerun these tests. But what I'm going to do is add a n to the end of the sequence. Then everything else here should produce the same result, right? Because that n, that last 8-mer will generate an na value and then it will, what? It should kick it out when we do the get all k-mers, right? And so all these values then should be the same because we're adding a nucleotide basically to everything. Sure enough that works. Something that occurs to me though is that this is all kind of hardwired for 8-mers, right? So I do get all k-mers but I'm not giving it the k-mer size. The default there is 8 as well. So I think I'm going to go ahead and add another test. And here then I will do, let's get all k-mers and let's do k-mer size equals 7. And we'll have to add that elsewhere. So we'll do that here for detected. And then here this should be a 7. So let's go ahead save and test that fails. Good. And so here I need to go ahead and add in k-mer size as, so that's good. So I think that's the only place. So let's go ahead and test that and it all passes. Wonderful. So now we've taken a sequence. We've converted to base 4. We've extracted all of the n-mers, how our k-mers, however big that k is. And then we've converted that from base 4 to base 10. And now we have returned a vector that with each cell representing the individual k-mer and indicated whether or not that k-mer exists. Okay. So now what we want to do is do that across all of our sequences. So now I'm going to do another test. So we'll do test that and then we'll say accurately detect k-mers across multiple sequences. All right. So I'm going to go ahead and copy the sequence that I have been working with here. But to keep things simple, I'm going to go ahead and shorten it, maybe cut it about in half there. And I'm going to make this a vector of values. And instead of putting a zero or an a at the end of that sequence, I'm going to make it a c, right? And so it's kind of hard for me to think in this base 3 instead of nucleotides. Anyway, so we'll have that. And again, to keep things simple, I'll do k-mer size of three. Because with eight, we're going to get a matrix or a vector that's got these like 65,536 rows versus if we do three, then we'll have 64 rows. So I'm expecting to get out of this function that I'm going to write as a matrix. So do matrix. And we're going to have I'm going to seed it with zeros. And I'm going to expect it to have n row equals 4 to the k-mer size. And n call equals two, because I have two sequences, right? So I'll call this expected. And so then my expected the rows, I'm going to use my functions to build out those indices values, right? So this is going to get a little bit funky in here, but roll with me here. So we'll do get all k-mers on sequence one. And we'll we'll do size k-mer size, right? So that will give us what? Well, I guess I need to load this and this. And then here, this will give us those values. And so then I need to shift these to base 10. So then we'll do base four to index on that. And so let's double check that this all works. Cool. And then those are going to be equal to one. And then I'll copy this. And the only thing we'll have to change is sequence two, right? And so now if we look at expected, we're going to expect 64 rows and two columns. Sure enough, that's what we get. And we can see that something didn't work quite right. That this column two is empty. So that's not a good sign. Ah, and I see the problem here is that I'm putting it into the row. But I'm not telling it what column. So this needs to be in column one. And this needs to be column two. And so now if we look at expected, I think this should look better. Sure enough, everything looks good. There should be one camer, right? These are off by one, right? Because I changed that last camer value. So that all looks good. Now we'll do detect camers across all sequences, right? And then we'll give that sequence, right? Because I could have called that sequences, whatever. And so then I'll call this my detect matrix. Then I expect equal expected and detect matrix. And I misspelled equal here. And again, if we test this, it's going to fail because it doesn't know this function, this function name is is kind of long. Maybe I'll remove the all to because the sequences will say kind of the all, right? So we'll go ahead and call this the function. And then we'll come back over here. And we'll do that function sequences. And then camer size, by default, again, we'll make eight, create our body here. So I could imagine doing something like detect camers sequences one with camer size. Right? So if I go ahead and load everything. And then I run this sequences not found. So let's see, so I call the sequence sequences, I'll update all these sequences. All right. Okay, I think that'll work. So again, if we load sequences, now it's loaded. And now we do detect camers on that. This is one value, right? And so basically what we did back out in the testing script was something like this, right? And so we could imagine looping over all possible sequences. And so you could do this with a for loop, but there's a better way. And so we'll do that with supply. So do supply. So do sequences. So for each value of sequences, we're going to put that through detect camers. And so we run that. And we get what looks like a matrix, right?  And actually, it's by default using eight, which is why there's so many values here, right? So again, to test this, I'll do camer size of three. And so it's returning a matrix like it's got 65,000 rows, right? But all of my camers are in the first 64, I believe, right? And so the problem there, actually, I don't know where they're going. Anyway, is that my supply isn't using the camer size. So I'll go ahead and do camer size equals camer size. And that will then pass the camer size argument into detect camers. Now when I run this, yes, I get 64 rows. And I get something that looks kind of like I would expect it to look. So let's go ahead and save. And I'm going to go ahead and comment this out for now, so that it doesn't get run with my test, I'll go ahead and test it. I'm getting an error, but I think I'm getting confused and trying to understand this error, because I have my values flipped here in the expect equal. It wants the expected in the second spot, not the first spot. So let's go ahead and rerun this and see if the errors make any more sense. So come back up here again, we're failing. And so the actual has 65,000 rows. The expected has 64 rows. And so again, why is that happening? And so the output of my function here is 65,000 rows, right? And that's because I'm not giving it the camer size. So I'll do camer size. Let's save that and test it again. So it's failing now because the dimension names is a list. And again, if we look at the output from this, that we find that we've got column names, right? Whereas there were no column names on our matrix. And so there's an argument we can give a supply, which is use dot names equals false. And again, if we run that now, we see that those column names are gone. Let's go ahead and save and test and hopefully it'll pass. Sure enough, that passes that did the trick. So now we have the ability to generate a matrix where our rows are our index values for our camers, and our columns are the different sequences. The next thing we need to get are those prior probabilities for each word. And so to do that, we're gonna have to sum across each of our camers, and then add 0.5 and divided by one plus the total number of sequences in our collection. So we'll go ahead and create another test. So I'll do test that. And then we'll do calculate word specific priors. All right. And so we'll go ahead and take, let's go ahead and take these again. And I'm going to add a third sequence, right. And it's going to be the same as the second sequence, because I want to make sure that there's some redundancy and some difference in the different camers that are found. And so now I'm going to again do detect matrix. And we'll go ahead and just copy this down, right. And again, if I do camera size three, and then detect matrix. So I'm going to pick a few rows from this that I'm going to be most interested in. And so I'll do 26, 29 and 30. Right. So 26, all three, 29, only one. And then 30, only two and three. Okay. I don't know why I wrote out three. Anyway, so kind of the math that we can think about with detect matrix is that we want to sum across the columns, right. And so an easy way to do that with base R is apply. So this is like s apply but apply. And so it takes a matrix or data frame, and then a dimension that you want to operate across. So one is rows and two is columns. So if I do one comma sum, it will then run a sum across each row of the data matrix. And so here we go. We see all that if I had made this two, then I should get three values, six, six and six. That's ominous. Let's go ahead and stick with one, where we again have 64 values.  That is the camer count. And again, I will add then 0.5 that adds 0.5 to each value. And then I will make that the numerator and divide by one plus the number of sequences, so I'll do length sequences. And then this gives me my word specific priors, right. And so this is my expected, right. I'll then create a value that I'll call priors. And this will be then calc word specific priors. And I'm thinking, do I want to give it the sequences or the detect matrix? I think I want to give it the detect matrix, because I think with a large number of reference sequences, detect matrix is actually going to take a bit of time to generate. And so I don't want to have to regenerate detect matrix multiple times for the priors as well as for the conditional probabilities. So instead, I'm going to give it the detect matrix. I don't need to give it the camer size, because that's already baked into the number of rows in the data frame, right? I could manually calculate the values for 26, 29 and 30, right? So it's an all three, that's going to be three plus 0.5 divided by one plus three, right? And so that is going to be something, maybe I'll wrap this in parentheses so I can copy and paste it into my console, right? And so this is 0.875, right? And then if I repeat this, but for one of the values, it's going to be 0.375. And then for two and three, so two, it's going to be 0.625. And then if I also do like, I think 64 was all zeros. So if I do 64, none, then that's going to be like zero plus 0.5, right? And that's going to be 0.125. All right. And so again, we can then do expect equal. And again, I could do expect equal, expected versus priors. But again, I manually did these. And in a way, I feel like doing this in the test is a little bit of a cheap way around the test. And so manually calculating it like this, I think is a little bit added benefit. So we'll go ahead and do priors expected, right? So that would be if I use the code, I could also do expect equal priors. And then I'll do 26. And I'm going to copy this a few times, four times for 26, 29, 30, and 64. Again, this is probably a bit redundant. But you can see a couple different ways of generating the test. Maybe people that might have more experience with test driven development can tell me what they think of these two different approaches to testing, whether it's kind of manually calculating things by hand versus writing the code. So we'll go ahead and test this and see what we get. And I introduced a typo here. Let me try that again. So again, it's fails because I don't have the function. So now we need to go ahead and generate the function calc word specific priors. Alright, and then we're going to give that our kmer matrix, right, which I was calling the detection matrix. Alright, and I'll go ahead and copy this code that I wrote back here. So the one thing that I am using here that I don't have access to is sequences. So this should be end call on detect matrix. So now this should pass. And I guess I, yep, my parentheses all look good. Go ahead and test that and should pass. Wonderful. Okay, so this gets us our word specific priors. And now we need to get our conditional probabilities. I'm going to go ahead and load everything. And so then we'll generate a new test, test that calculate specific conditional probabilities. And I'm going to borrow some of this from up here. Right, so I've got my kmer size, my sequences, and my detection matrix. The other thing I'm going to need to give it are my genera.  And I think that should work well. So again, these two sequences are different from this sequence. And so they go into a different genus. Again, this is all kind of test code. And something simple, so that we can kind of manually work through the, the calculations to make sure that what we're doing with the code actually generates the right values. So I'll go ahead and run these lines. So I have it all loaded. So again, the calculation, so we'll have mwi, which is the count within the genus plus pi, which is the prior, right? So that added together divided by m plus one, where m is the total number of sequences in the genus. So I'm going to get the priors. And so again, my function here was, or I'll go ahead and just copy this line. And I get my priors, right? Good. And the interesting values are up here. And maybe I'll go ahead and copy this whole thing. All right, copy that down. I don't need this just yet. And so again, if I have two genera, and I'm using mwi, then let's see. So 26 is an all three. And so the, I'm going to have a two and a one, right? So I'll have genus A has, has the camer in one sequence and genus B has it in two sequences, right? And so then I also have the m, which is going to be one comma two, right? And so one of the nice things about R being what's called vectorized is that I can do something like this, right? So that's going to add a half to one and two. And then it's going to add, well, I don't want it to add three, I want it to add one, right? And so then this is going to add one to one and two. And then I can get the ratio, which will be 0.75 and 0.833. Okay. Cool. And for only one having it, so only A has camer 29, then again, I can think about this formula the same way. And so only one has it. And so here this is going to be zero, right? And so that should work, right? And that gives us this. And then only two and three having it will be, again, copying this code down. It's going to be only B having it. So it's going to be zero and two. And again, if we run that, we get 0.25 and 0.833. Very good. So again, these are going to be my expected values. And so this last one that doesn't have it at all in either of the genera, we'll do this, so it'll be zero and zero. Again, these values and the denominator, the m values are staying at one and two because that's how many sequences we have in the genus. So that doesn't change. And so that gets us 0.25 and 0.16666, which makes sense compared to the two previous cases, right? So this was what we got when it was absent from a and this is what we got when it was absent from B. Cool. So these are test values. And so I can go ahead and I think copy this code directly in here for my expected values. And I'll do that here real quick. All right. And then I'm going to have, I'll remove that. And I'll do my conditional prob. So I'll call this calc genus conditional prob. And I will then give that detect matrix. Okay. And again, if we test this, it's going to fail. Oh, it doesn't fail or it does fail because I can't find this function, but I didn't put this in here. And so I need to modify this actually too. So I'll go ahead and put a comma here. And so this will be row 26, both columns. And so again, it's going to fail as it says here because we couldn't find the function. So we'll go ahead and grab that and come over here, function detect matrix. And I think the other thing I need to give it is the word specific prior, right? And so go ahead and give it that. And here we'll also give it the word specific priors. Maybe I'll put this down a line so we can see everything without having to score left and right. All right. And do the same thing here. Cool. All right. And so again, what we're thinking about. So another piece of information I realize we need are the genera, right? And because we're going to need to know how to aggregate the columns of detect matrix. So there's a few pieces of information that I need to get from these three values. I'm going to need to get, well, really one main thing, I'm going to need to get the total number of sequences in each genus. And I'm going to also need to aggregate the values, the columns and detect matrix by their genus, right? And so I can start with, like, table genera. And this gives me A and B. But it's a weird data structure that I don't quite understand why it does this, that it's a table format. And it's got dimension names. I'd rather it to be a vector. And so what I could perhaps do is send this to as dot vector. And that returns it as a vector. And so I will then do genus counts. And so now I know I have two genera, right? And so the output of my conditional probabilities. So I'll do genus conditional prob, I'll do matrix. And I'll give everything a value of zero initially. And my n row will be the number of row on the detect matrix. And the number of columns will be genus counts, actually not genus counts, length of genus counts. I could have for n row, also used length of, well, word specific priors, not Calc word specific priors. Let's see, I'm probably trying to go a little too fast here. So this is priors, right? Okay. And so this is initializing my matrix. And again, if we look at this, we see that we've got two columns, right, for each of the two genera. And we then have our 64 rows for the different possible k-mers. And so what we want to do next is to aggregate the values in detect matrix to aggregate and calculate the number of sequences in each genus that had a k-mer. And so I'm going to use a for loop. So for loops get a bad rap in R. Generally, for loops are a problem if you are growing a vector or growing a matrix. They're also a problem if you have nested for loops, if you have a for loop within a for loop, those are bad. So what we're going to do here instead is that we've already created the matrix, right? And so we're not going to have to expand the matrix. And so when you expand the matrix, it goes really slow because it's constantly looking for new places to put the new matrix that you've created. And so I'll do four i in one colon length genus counts. I'm going to go ahead and call this n genera on length, yeah, length genus counts. Because I'm using this a couple times. So I'll go ahead and plop that in there. And then here. All right. And so we're going to we're going to index over our detect matrix, right? So we'll do detect matrix. So I'm sitting here realizing that my genera is coming in as a string rather than as an integer. And so this again is the same type of problem that we had with our sequences. So I'm going to go ahead and recast these as integers, right? And we'll have to figure out something later where we when we're reading in the genera, we can convert it to a number. And so this needs to be an integer, not a character. Okay. And so then genus counts, if I look at genus counts, one and two are the values in one and two, right? The number of times we see each of those. Okay. And so then let's see, that all works. Okay. So we're going to then use detect matrix, all the rows and the ith column. I'm going to add that to let's see. Maybe before I call it genus conditional prob, I'll call it genus count. And so then we'll add that to genus count on all rows. And then I is going to be indexed into genera to figure out what genus it is, right? So we'll do genera, I. So if I is two, then genera, I will be two, right? If I is three, then genera, I is going to be two, right? And so we're going to then be adding this to the existing value of this. But we need to assign it back to this, right? Okay. So that then should get us our genus counts. And so let's clean this up a little bit. And now if we look at genus count, let's see what we've got here. So we've got our 64 rows. And it's not quite doing what I had anticipated. We're basically getting out the detection, not the genus count. And so I see the problem that I'm indexing over the genera, not the number of sequences, right? And so n sequences is going to be length gena genera. All right. So sometimes these things get a little bit confusing. And so I'll go ahead and plop that in there. And let's go ahead and start this again. And now if I do genus count, again, I have 64 rows. And I see sure enough, I've got these with the correct number of sequences that had that camer in that genus. Cool. So now we have genus count. And now we need to go ahead and do that conversion that I had here, right, to get the conditional probability. And maybe I'll go ahead and throw this up here. Maybe I'll put it up there. At some point, I need to come through and do a better job of documenting my code. Because at this point, there's really no documentation. And that's a really bad example to be setting. So again, we have genus count, we're going to go ahead and then add the word specific priors. Okay. And so again, that's going to be in the numerator. And it doesn't like my word specific priors because word specific priors is the same as prior. It doesn't like prior. Why don't you like priors? Oh, priors. I didn't hear you correct me on that one. All right. So now if we do this, sure enough, we get the two added to each other, right? All these were like zeros. And so point one, two, five was the prior for a camer where it wasn't found in any sequence, right? And here we see those others. And so good. And now we need to divide it by m plus one. And so m plus one is going to be the genus counts plus one, right? And so if we run that, then we get some kind of funny results, right? So this 64, I would not expect to be 0.41 and 0.41, right? I would expect it to perhaps be 0.41 and 0.6, or something like that. And so one of the challenges with vectorized code in R is getting the dimensions right. So this is a 64 row by two column matrix, whereas this is a one row by two column matrix, right? And so we need to go ahead and transpose with the t function the numerator, right? So now we have two rows and all these columns. And then we can then divide by the vector. And so now we get something that makes a bit more sense, right? And so that's good. But we need to like retranspose it, right? And so then we need to take the whole thing and transpose it. So let's go ahead and save that and let's test it and see if it passes our test. And so it's failing. And I noticed that I did something silly when I was calculating the expected, right, that I have this 0.5 here. And that was part of the formula for the word specific prior. And so I need to modify that to be 0.875 here. And then what did I have up here 0.375. And then 0.625. And then what 0.125. Test again. And so I'm still getting a fail on my last test. And it's liking the first value, the first actual unexpected, but not the second. And I believe that is because I left in a two, rather than a zero, because 64 kmer 64 isn't found in either of the genera. Now it should pass. It passes. Wonderful. So I have found using test driven development to be just really fascinating. What ends up happening are I guess two things worth commenting on, I think, is that I get code that is a lot more concise and in my mind better designed. And that I would probably have made a bunch of these functions all one function. And instead, I feel like the code is a lot better self documenting and understanding what's going on. The other thing that I find is that as I kind of showed in some of these typos that I introduced by copying and pasting on whatever, is that first of all, I'm prone to making errors myself. And second of all, by kind of going through this, I better understand what the code is trying to do. Okay. So again, I'd be curious what your experience has been with test driven development. So far, I really like it. I'm a little bit worried as things are going to get even more complicated, how we're going to go about doing test driven development. But for now, I'm pretty happy with it. And it's, it's comforting to me that we have all these tests. And they run fairly quickly. So again, in this episode, we did these last two points in the reference column of calculating the prior word specific prior, as well as the conditional probability for each genus for each word. And so we'll see where we go next. But hopefully you're enjoying this process of building out this phyletyper r package. So please make sure that you've subscribed to the channel, and we'll see you next time for another episode of Code Club.


Okay, I am fully aware that the establishment is afraid of Bernie videos are getting a little bit redundant for me at this point But you've got to understand I have been challenging these ghouls now For almost five years and to see them squirm at the prospect of a Bernie Sanders presidency like I am I'm truly Enjoying it and I find it fascinating like the tactics in particular that they are trying to use to dissuade people You know away from supporting Bernie Sanders It's honestly bold that they haven't changed anything Since 2016 like you would have expected them to adapt and their tactics against the Bernie Sanders to evolve But I think that they're starting to realize that nothing they say will dissuade people especially young people From you know supporting Bernie Sanders We're going to commit to supporting him because he's the only person who has a really transformative agenda That opts for structural change and he has the movement To facilitate this change in actuality get what he wants codified into law So I want to read you one last story on this subject for now from the Associated Press This is by Steve Peeples and Alexandra Jaffe who report Increasingly alarmed that Bernie Sanders could become their party's presidential nominee Establishment minded Democrats are warning primary voters that the self-described Democratic socialist would struggle to defeat President Donald Trump and hurt the party's chances In premier House Senate and governor's races the urgent warnings come as sanders shows new signs of strength On the ground in the first two states on the presidential primary calendar Iowa and New Hampshire backed by a dominant fundraising operation The Vermont senator has largely escaped close scrutiny over the last year Yeah, right as his rivals doubted the quirky 78 year olds ability to win the nomination But less than a month before iowa's kickoff caucuses The doubters are being forced to take sanders seriously Former chicago mayor rom immanuel previously a senior aide to president brach obama warned democrats that sanders status as a democratic socialist And his unwavering support for medicare for all won't play well among swing voters in the states that matter most in 2020 You need a candidate with a message that can help us win Swing voters in battleground states immanuel said in an interview the degree of difficulty dramatically increases under a bernie sanders candidacy It just gets a lot harder, right? So i'm assuming that he believes we need someone more moderate Like hillary clinton or tim cane Like it's honestly amazing to me that they haven't changed their 2016 fear mongering at all They're still using the same electability argument against bernie sanders Even after their argument is a proven failure. We put up a moderate and she lost Why haven't you even tried to change your message even a little bit? Like i honestly believed that they weren't dumb enough to use the same exact argument against bernie sanders And they are like i like i'm not under this delusion that democratic party strategists Are competent i think they're some of the dumbest people in america to be honest But i at least thought they had the self-awareness to not try out the same fear mongering that We need a centrist to win but they're doing that again after it was a proven Catastrophe and Donald Trump is president. I mean you really have to be Confident in yourself to use the same argument twice But i mean it's just astounding that someone like ron immanuel of all people won Thinks that anyone takes him seriously and cares what he has to say but two Believes that all of a sudden this time in 2020 we're going to accept His electability argument that we need a moderate to take on donald trump sure jen I mean what do you say about this these people are clueless No wonder why democrats under obama lost more than a thousand seats They have no strategy and what i like is he suggests that Bernie sanders being at the top of the ticket is actually going to hurt down ballot democrats No, what we need is high turnout and part of that like a really huge portion of the electorate that we need To increase voter turnout so we win our young people Riddle me this genius who is the candidate that is running away with the youth vote? It's bernie sanders. I believe uh bernie sanders got more Votes from young people than hillary clinton and donald trump combined in 2016 So do you honestly believe that down ticket democrats will be worse off?  What do you say? So i apologize for constantly making videos about how the establishment is afraid of bernie sanders But i truly am enjoying this it's not a foregone conclusion that he will win the nomination and yes We have to work very hard for it, but i am enjoying watching these people You know shake at the prospect of a sanders nomination after all of the things that they put us through after their incompetence and hubris led to Donald trump winning i'm excited to see them Fear because you know it's not gonna work. It's not going to work You're not going to dissuade us from supporting bernie sanders again He's the one who has the best shot nobody's a foregone conclusion against donald trump But if you honestly believe that a moderate increases our odds You really are out of touch and more clueless than even i initially thought Subscribe if you like this video fox Mike's tremendous and he's doing a really really good job Many people are telling me about how wonderful the humanist report is Bigly


here on Think Tech. I'm Jay Fadale. We're going to remember Westlock today. Westlock is a story that very few people in Hawaii know about, but they should. It's the second Pearl Harbor took place on May 21st, 1944. And May 21st is coming soon, a couple days away from us now. And Dolores Gutman, Steve Gutman, a long marriage and dedicated, defined by their activism in the community, but so many organizations. We don't have time in a short show here to describe all the organizations and causes they have been working on together all these years. And I admire and commend them for their activities in that regard. Today, we're talking about Westlock, a very, very important story. And I suggested our viewers take notes on this because they may not know anything about what happened in Westlock. So the first question, Dolores, I put to you, why are you interested in what happened at Westlock? Oh, it was brought to my attention. In 2009, I never heard of Westlock until the Navy called me and said that this is a bit that you need to be be part of your history here in Hawaii. That was my first knowledge of it, and I'm still learning. Quite remarkable. And Steve, I'd like to say to you, you know, when I was in the Coast Guard, I studied casualties, I investigated casualties, a number of them, serious casualties, right on through casualties that were interesting to the presidency and Congress. However, nothing came close to the investigation. Nothing I've ever done came anywhere close to what happened at Westlock and all the investigations that happened. And all the reports were made, including a book called The Second Pearl Harbor. Gene Eric Sallacher wrote a book only a few years ago. And, you know, it was it was like classified information until the 60s or 70s. And for that reason, nobody knew about it. Nobody captured it. The reports were written for the Navy was all internal and classified. And finally, we have this this positive book, which is on Amazon by Sallacher. And I find it very interesting that he does what I would have done in the Coast Guard, he examines every single fact the book is loaded with exactly what happened. So Steve, make yourself a legal investigator now as a lawyer, then tell us in a few words what happened on May 21, May 21, 1944. Well, actually, Dolores does a better job of describing the incident. But I really think we ought to have her go through it. Okay, I take your point. Dolores, you describe the incident. Well, the Second Pearl Harbor really kind of skipped over some factors. He talked about the LS3, the LST vessels in Pearl Harbor, and those things, but they didn't talk about the incident itself in detail. He skipped over the fact that what happened actually there in terms of the explosion on LST 353, which were being unloaded by the 29th decontamination unit from Schoolfield Barracks. And the ship was overloaded and they lost two or three roll-offs on LS353 as it was moving around Maui. And so the ship came back to Pearl Harbor to be reloaded. And as they were reloaded with no training or anything, the exposure occurred in the afternoon. They arrived around 7 o'clock, about over 100 or so men from Schoolfield arrived at Pearl Harbor around 7 o'clock to unload the ship on the 7th. That was the Sunday morning, May 21, 1944. And so that they, the secret part, and the Navy actually preferred not to talk about it because the men were not trained. And in the second day, in the second event happened me on July 17th at Port Chicago. These men were unloading ammunition and gasoline on this LS353 that blew up the explosion. And the bodies were flown all over the place at Pearl Harbor. And many bodies are still, the boat and everything is still down in the Walker Bay. And we have a lot of history and I have names of people that survive. And we will talk about that on Friday, some of them. Well, tell us what's happening on Friday. On Friday, May 20th, which is we're celebrating the 11th anniversary of the West Lock and Turney's life and memory. This began in 2010 at the National Memorial Cemetery of the Pacific. And there are 39 graves, I know Mark Graves with butterflies in them. They have to be analyzed by the POWMIA, which is the DPAA at Joint Base Pearl Harbor. So the celebration is to memorialize those men that are buried there in unmarked graves, 39 of them. And it began at 2 o'clock on Friday, May 20th. And it's about a 45 minutes to 60 minute services. And it's a military protocol. And it's in collaborative, the Obama-Hawaiian Africana Museum is working in collaboration with Joint Military Forces of Hawaii to celebrate that. Okay. So there's an African-American connection here. And I want to explore that with you. There are 559 people injured or killed, something I recall, 136 were killed. Well, it's something similar to that. They don't know exactly how many people, because we only pick the body parts off the water. And some of them would never recover. I've gone down Joint Base Pearl Harbor with different admirals in general for the last 10 years. And I get more information every time I go with them down to, in the back of the high security area about this incident. And they're still unfolding. Yeah, there were a lot of reports written. And they're inconsistent in many ways. So we don't know the whole story yet. The Board of Inquiry was initiated the very day after this happened. But one thing I'd like to offer you is that there was an inconsistency as to the cause. And there was an inconsistency as to why it was kept classified. Let me say what I mean. There was some talk about a Japanese submarine, a one man submarine out there, and some investigation done on that and the possibility that that caused the explosion. The explosion was huge. It sank six LSDs and those are large ships. And those ships were loaded with tanks and war material and mortar rounds, 3,000 tons of explosives on these six ships. And it really destroyed West Block at the time, including structures on the beach. In any event, I guess the prevailing theory now is that the men were untrained, as you say. There was gasoline, exposed gasoline. And some fellow was smoking a cigarette. And the cigarettes set off the gasoline and the gasoline set off the ammunition. I think there are probably other theories too. And there are multiple theories about why the Navy originally kept it secret. This was part of a special project, delivering this ammunition to the Marianas to clear the Marianas so they could fly a B-29 into over Tokyo. And so they managed to get their act together only a day or two after by bringing other LSDs in to do the same job and they carried out the mission, the convoy, if you will, to the Marianas, pretty much on schedule, which is really a statement. But since this was a highly classified mission, they didn't want to talk about it. Yeah. And now the state of Hawaii was still under martial law. And because there was so much tension because of what was happening in Japan and they're planning to, you know, invade the Marriott Islands and to make a secret kind of impact. But the Japanese ships were out there from California and all around the Pacific and everything. So they had to be very careful. And so what happened is they needed to test some of the ship because they were overloaded. And we lost three roll-off LSDs on those of the roll-off on the LSD, the larger boat. And so that was why the army was, you know, tasked with unloading and reloading the LSD-353 that blew up. And the reason the guys didn't know how to handle it, they were just rolling live ammunition down the chutes where, you know, they just paced live ammunition on things and onto a truck. I have some pictures showing them doing that. And they don't have a clue about the danger and also the gasoline that tanks that are also on board. So it was easy. It was lots of ways that, you know, the explosion began. And it was just, and when the ship blew up, it was it was, the people on it was just mesmerized. Period. What are the pictures show, Maurice? The picture, the picture just shows LSD-353 just into explosion and it's spanned all over Walker Bay and the adjacent ships that were nestled together. That's how the six ships got, you know, the fire on them. And then one guy, which you will be seeing in our program on Friday, his rider was blown over on the west side, on the Warpio side of the day. And they didn't run him to 10 days later. Other barred apart fingers and arms and all kinds of things were just piqued up off the water. And then I talked to another gentleman who worked in the Navy Yard. He had picked up some of the body parts off the water. And then people later on, even the water parts were still laying all over George Bay's Pearl Harbor in 43. I mean 42 when this happened. So again, they were deteriorating in that kind of thing. So in the Navy, and it's okay, it's historical, Portugal and West Hawk incidents were being handled by Black men, which is the dirty work. Yeah, that's so that's one thing I want to explore with you. Of the people that were killed, at least half of them. More than half. More than half. But what are your numbers? What is it, Steve? Well, the numbers they have, they still, although POWM, they sent me a whole list of things and I've gotten a lot of some declassified information. The numbers vary all over the place. So they were... Why were there so many African American men in such a dangerous job? Why was that? Because this is just the tip of the iceberg. This was the two incidents, the one that were Pearl Harbor on May 21st, 44, and in Fort Chicago, July 17th, 1944. Those are the two events. Another event also happened in the Marriott Islands. I'm known in the ships. That one, I'm not talking about at the moment, my researcher did work on that, but we just talk about Pearl Harbor here. And that story is not real. And I'm not sure why do we have all the people that died because they have military numbers. And the list that I have are military numbers and the families never heard from these people. And more recently, I've been contacted. I don't know why I'm always been contacted on this. They did find a couple of people, bodies and names listed in the last couple of years or so. Remember, Jane, this whole time is this is when the service was still segregated. And this was grunt work. And the grunt work was frequently done by the African Americans. Okay, that explains it, you know, at Fort Chicago and in Westlock. And the difference with the Fort Chicago was that could be seen actually in San Francisco. So the Navy couldn't put the secret tabs on it like they did with Westlock. Here with the Marshall ball and everything else, they were able to keep it under wraps. The real question is why did it stay labeled secret into the 60s? I mean, it's understandable why initially they did it, but it really should have been reported. Well, do you think it was intentional with holding of information from the public? It could be just a mistake. Why would they have continued? Because it was segregated military at the time. In WACP was given the military a hard time in terms of positions of blacks serving in World War II, including Tuskegee Airmen and those people. And here in Hawaii, all of the bases, all the rough work with the engineers, I think they're core engineers they call themselves, the white officers, they were sent to prepare the way into bear the hours. And then the blacks would come in into Pearl Harbor to pick up the pieces and to do all the grudge work at Pearl Harbor that needed to be done. And they don't get credit for this. And the second Pearl Harbor doesn't even deal with that part of the story at all. No, as I read up on this, I thought to myself, this is a story that's basically unknown, even here, even here in Hawaii. And it's very good that you are covering it, exposing it. Well, you have to keep in mind that Hawaii was under martial law. And the Asian people in particular, because they didn't know a lot of mainland people could not tell different ethnic groups of Asian ancestry. And they were monitored day and night. And the people, even today, when we also talked about the Surrey, the capital with the Disturre Foundation, Hawaii Foundation, a few years ago, people remember the incident, but they were not allowed to talk about it during World War II. They were not, the newspaper only had about a short five or six lines about it. The incident happened. They didn't even say where it was. Yeah, you can imagine. I have that document. You can imagine how the Navy was affected by this. They were probably astounded that it happened in the first place. It was a major event in so many ways that affected their whole position in the Pacific. They didn't want to talk about it. They gagged, made a gag order for the press here. They wouldn't discuss it. At the same time, they galvanized themselves on two fronts to have a court of inquiry immediately look into it. And I think they were paranoid, too. They thought that it was a Japanese submarine. They couldn't clear that possibility. And at the same time, they were afraid of public opinion about it. Right, exactly. And the narrow report have the court of inquiry. I haven't seen that yet. And they talk about the court of inquiry to people that survive the incident and also more about the Navy. But that's research for future generations, not for me. Steve, what would you add to all of that? Obviously, you're both interested in this. You're both working on it, so to speak, advancing public knowledge about it. What's your point of view? Actually, I would like to talk a little more about the memorial service that's really on Friday and the fact that I think it's really important if people can be present and celebrate the lives of these people. Because, party, there's so many of them that we really don't have names. And it's really sad in terms of what occurred. Yeah, that's one of the points in what you published on the event to give them names because my recollection across the numbers are not settled. But there were 29 body parts found. They couldn't find any bodies because the explosion was so violent. Series of explosions, I should say. I mean, six LSDs blew up with ammunition of 3,000 tons of ammunition, including mortar rounds, artillery, so that there was really nothing left of anyone. And the 29 body parts were buried. But at the time, there was no technology to determine what belonged to who. And you alluded to the possibility that they can now find out using modern technology. Are they putting names on these graves? Is that what's happening? Well, right now, they have to untune the 39 body parts up there. That is one of the things that the POW, the FIA office have to do here for Harvard. They have, we've talked about it, that they need to do that so they can identify those body parts. They could identify some names. Several families have come forth, both black and white, given their names and they were able to track. This is POW, MIA office, was able to track their names down and find them, and they are listed in the National Cemetery. These suggest names don't have anything to do with the body parts. So that's the second thing that has to be done so that the families, this has been 78 years ago, the families have never heard from that family members again. And you notice that I said 39 graves with body parts in them, not bodies, not bodies, because they were blown to the smithering when the LS-354 and the closest to LS-353 also exploded with the same tenacity as the LS-353. So you have a conglomerate here and a lot of people it says your word, his word, and their word. We're still unfolding this story, so the best that we are going to get in this research, we have to look at the Code of Inquiry reports and how they talk about it. I hope you talk about this book, The Second Pearl Harbor by Jean Eric Selector. It's actually on Amazon and you can get it. Yeah, I have a, except for, I talked to the guy after he sent me a song. The only part, as I said, he was not interested in the African American peace of it. He wasn't interested in talking about segregation. And you know, the army was only desegregated in 1948. So you deal with a lot of history. Do you think that what happened at West Lock led to the desegregation in 1948? No, I'm not saying that. No, I'm not saying that. But you have to kind of think about how our country was, you know, segregated in Jim Crow was evident everywhere. And this included the workers in the factories that helped to build the aircraft while the men are at war. And how the migration came to the West to help work in the factories. So there are many pieces of this story that helps to tell their larger narrative. And the best I can talk about Hawaii, because that history is under the radar that people don't talk about what they did here at all. And in Pearl Harbor, Pearl City, Kwansoa 33 was part of Manana barracks. And I don't know, another base that black barracks were outside of Fort Shaffter. This is our Navy historian Jeff Dodge told me about. They just dismantled that one all together like they did the ones in the ever beach, ever side. So a lot of the history is still under radar. They're dealing with Pearl Harbor here in Hawaii. I understand. But this is not just a lesson in history. Although it is a very interesting lesson. I hate to say this, but it could make a very interesting movie, for example, to cover it in detail. I'm not sure there's a lot of information or people that can give the details aside what's written in these reports. But I think there's lessons to be learned beyond the historical rendition and analysis. And I'd like to ask you guys to talk about that. Steve, what can we learn as we learn about what happened here in Westlock? What can we learn for the future for Hawaii, for the military, for, I don't know, race relations? Well, as far as the actual incident itself, just in terms of the importance of training, and the fact that the people were not properly trained, certainly led to the numbers increasing. The mere fact that the explosion occurred would have led to a fair number of deaths. But it got compounded by the fact that people really didn't know what to be doing initially in terms of how to react and address the problem as it was developing. Who are us? Well, I think that what we need to do is continue. I'm working with a historian and he will be at our services on Friday. We're looking at how to mitigate the situation and tell these at this particular part of the story. We're looking at, I think, at George Bates Pearl Harbor. They want to go on the Westlock side. They're looking at this man on a walk over there. But we need to do something to make sure that our young people, our future generation, know about this particular one so that they can also be able to prevent such a things occurring again, incidents, no matter what they are. So in history informs the future. So I think here in Pearl Harbor says the World War II began here. It is very imperative that we tell a larger narrative about all of the people that participated in World War II in the Pacific. The World War II in the Pacific story has not been told adequately at all, which includes the people of Afghanistan, the Japanese, because they did so well in 442 in Europe. They stand out. But the Filipinos and the Chinese and the Hawaiians and African Americans, our story here in the Pacific are not told well. And we need scholars and researchers to unfold that story. And like you said, a documentary will be really well done if they look at the whole story, not piecemeal it. Well, the other thing about this, and it goes especially now in the time of Ukraine and violence in Ukraine is we forget just how war goes. We forget the violence. We forget how dangerous it is to handle ammunition, 3,000 tons of ammunition.  Exactly. Only 60 days before. So it's really a lesson in making us understand about war, about the lethal consequences of even relatively innocent acts of loading a barge. And I don't think people understand that. We've been sort of cauterized about the violence. We've heard it all, Pearl Harbor. We've seen the pictures of the ships smoking and sinking and what have you and look at the Arizona Memorial and all this. But the fact is that we don't fully appreciate the violence of what happened and the guests surrounding us and the body. This is a factor which is very prevalent that we can talk about after the COVID and the pandemic. We need to talk about the real story of war, especially looking at Ukraine and what's happening there. And that situation is not any different than happening in World War II here in Hawaii and across the Pacific Islands and also Europe. And again, I think that it requires us to have a dialogue. And I think that would be a nice program to have to actually talk about it, that having from different sectors and people from different sectors to talk about it in terms of how war has impacted our lives. And we need to put, we need to kind of start looking at for the future generation to kind of minimize this and mitigate it in some way. Because war is not, it is not acceptable. And along too many innocent people died, by the way. And can we get along otherwise? And I think we need to be at the table to actually talk about one thing that COVID has done and the pandemic crisis. I think now PearlCon, it can bring us together to have a conversation. Yep. Well, and the great tragedy is in war, in the fog of war, terrible things happen to people, they lose their lives. And that is, that is something every time. And as they say, the history is told by the survivors. But the people who were killed, they don't have a chance to tell them. They don't have a voice. And we are, that's why the 20th, the May 20th at the natural cemetery, we're that voice. And we need to kind of mitigate it in some way to, so it doesn't happen again. So that they do have a voice. And I thank you for inviting us on the show to talk about that. This is beginning of a long, a long narrative that should take place on your show and on our media. Yes, we want it. We want to cover this. We want people to be fully informed and thoughtful about it. So Steve, let me ask you, have we covered the points that you would have liked to see us cover today? Is there anything you want to add in terms of, you know, what we should take from this discussion? No, I think you've covered the primary, primary points. I mean, it's an incident that happened. It easily happened again. And it's something that people need to need to say their proper prayers for. Yeah, sometimes I think Hawaii doesn't think of its history in the comprehensive way that you guys are talking about. And we have to be mindful of history, or we will repeat it. And so I think it's very valuable that you're bringing this to public attention. Well, you know, the other thing though, Ray Emory, who just died last year, he was that voice before he was he it was a one man show and he worked at it ferociously until he died. And he was actually here's my anchor and put the wind wind beneath the wing to get involved in this project. And he would not let me walk away with it. But he gave me all of the support to tell the story. And for him, making sure that the unknown people that died on December the 741 that their lives were meaningful and that we shouldn't forget them. And so the same thing happened. He said he was in court when May 21st 44 days that occurred. So he witnessed it. You know, part of think tech's approach to things is to make people to take people beyond their daily lives, their daily grind, you know, whatever they do on a given day, take them out of their comfort zones, try to give them a world view, not only about the present, but about the past. And I think that if you want to, if you want to understand Hawaii, right down to the core, you have to understand things like this, too. It has to be in our historical lexicon, it has to be things we think about and we build into our world view or at least our Hawaii view. So thank you very much for this discussion. Dolores and Steve, I really appreciate you coming around. Thank you for you. And I wish you a productive event here coming up soon. Thank you very much. Thank you very much, Jay. Really appreciate it. Aloha. Thank you so much for watching Think Tech Hawaii. If you like what we do, please like us and click the subscribe button on YouTube and the follow button on Vimeo. You can also follow us on Facebook, Instagram, Twitter, and LinkedIn, and donate to us at thinktechhawaii.com. Mahalo.


I am Zor.  Today, we will talk about equations and how to solve them using invariant transformations. First of all, what is an equation? Well, everybody now, something like x squared equals to 1 represents an equation. Right, that's absolutely correct. But I would like to generalize this concept and basically talk about equations in general, what are equations in general. But look at this one. On the left side, you have some function, basically. x squared represents a function. So you can say that on the left side of the equation, we always have some kind of function. Now, what is a function? Function is some kind of a combination of domain where arguments are taken from, co-domain, where the function takes value, and some kind of a rule which explains how to get from the domain to the corresponding variable. So basically, these arrows represent the rules. So if you take this element of the domain, the function transforms it into this element of a co-domain, from this to this, et cetera. That's the concept of function, a domain, co-domain, and certain set of rules. So in this particular case, we usually are talking about some algebraic expression of the function, which basically assumes that domain and co-domain are numerical. Now, usually, the most frequently, I would say, case in algebra is when the function is considered to be defined on the domain and co-domain real numbers. Sometimes it's complex numbers. Sometimes equation is defined on a set of integer numbers. Actually, one of the most famous equations in the history of mathematics, which presented by Thames's French mathematician Fermat, was actually an equation in integer numbers, a great theorem of Fermat. But anyway, usually in school, in algebra, people are considering most often the equations where both domain and co-domain are real numbers, and f of x is represented by some kind of algebraic expression on x-ray. So that's on the left. On the right, since function takes values in the area of co-domain, and we're talking about ecology, then basically the element which is supposed to be on the right is an element of the co-domain. Well, basically, that's what the equation is. It's the algebraic expression of function defined on certain numerical domain, usually real or complex numbers. And it takes values in corresponding real or complex numerical numbers. And on the right, we have one particular element from the co-domain. And that's the ecology between them, and it represents an equation. So what is an equation? We understand. Next is basically what is the solution of this equation, because the purpose of the equation is basically to solve it. So what is a solution? Well, let's talk about this graphically again. If this is an element B, which I'm talking about right now, then to solve equation means to find all elements from the domain which are mapped by this function into this element B. Let's say it's A1 and A2. By the way, it's not necessarily that we have any solution to the equation in this domain. Maybe there is none. So there are certain values in the co-domain which are not values of this particular function defined in a particular argument. Another case is when we have only one element of the domain which is transformed by the function into this element B. Or we can many. Let me exemplify it. This particular equation, x where it goes 1, has two solutions in the area of complex number, in the area of real numbers even, plus and minus 1, because 1 squared is 1 and minus 1 squared is 1. So we have two solutions in the area of real numbers. Now, if I will tell you that I would like to solve this equation in the area of positive numbers, then I have only one solution, only one, because minus 1 doesn't belong to my domain. Function was defined originally in a set of positive numbers only, so there are no solutions. Another example would be if I have an equation of x squared equals to minus 1, which obviously has no solutions in the area of real numbers, but it has two solutions among the complex numbers, plus i and minus i, both squared gives you minus 1. So it's very important from the very beginning that we are talking about equation to talk about the function and how it's defined. This particular function on the left should be completely defined, which means there is a domain and there is a codomain and there are rules. In this particular case, if we are saying that the domain is real, no solutions. If we are saying that the domain is complex, set of complex numbers, we have two solutions. OK, done with that. So we know what is an equation. It's an algebraic expression of the equality between the certain function and certain element of its codomain. We know what the solution is. That's the 0, 1, or many different values of the domain which are transferred into this particular element of the codomain. So now, probably the most important question is how to solve equations. And I'm sure you all know that there are tons of different ways to solve different equations. There are certain techniques. And the goal which I'm trying to achieve here is to generalize the process of solving equation. And this generalization I would like to present using the concept of invariant transformations. All right, so let's think about what is invariant transformation. And let me start from the example. If you have something like x plus 10 equals 13, and I would like to solve this particular equation, let's talk for definiteness that we are talking about real numbers. Well, again, I'm sure everybody knows that what we can do is we can subtract 10 from both sides of the equation, and we will get basically x equals 3. Wow, but what did we do, actually? And that's what's very important. I said we subtracted 10 from both sides of the equation. Well, we transformed one equation, original one, into a new one, which is simpler. So this transformation of the equation is the basis which I'm just trying to talk about when I'm talking about solutions general solutions to the equations. We are transforming equations into a different type, which might be simpler, like in this particular case, and deliver solution. So that's what transformation is. We are transforming original equation into a different one. Now, how can it be generalized? OK, let's consider that, again, we have this domain, codemain, and the function f. This is domain. This is codemain. Now, in this case, let's consider that both of them are real numbers. Again, it doesn't really matter. So what we did, we applied the same transformation to both sides. Now, both sides are elements of the codemain, right? Because this is the function which has values in the codemain, and this is the element of the codemain. So both sides have been transformed, and we actually were still within the codemain, because this is still codemain, and this is still an element of the codemain. So what did we do? From one element of the codemain, this or this, we basically moved to another element of the codemain. Well, this is a transformation. Well, another word for this is a function, by the way. So we applied another function on both sides of the equation. In this case, the function is what? Basically, the function is x minus 10. That's the general algebraic expression of the function which we have applied to both sides. x, in the first case, is this x plus 10, and the minus 10, it will be only x. On the right side of the equation, x is 13, and x minus 10 is 3. So we have applied a function which is defined in the codemain, and takes values in the codemain, and it's an algebraic expression at x minus 10. So what basically it means from the general standpoint is, let's consider we have a function t of x, which transforms the same codemain which was here into itself somehow. This is my function x minus 10. From any element of the codemain, which happened to be real numbers in this case, my function value is this element minus 10. So that's the transformation which I have applied. Now, what kind of transformations can be applied? A, well, not quite. And here is why. What we would like to have is, we would like to have transformed equation to be absolutely equivalent to the original one. Equivalent in what way? Well, every solution of this one should be a solution of this, and every solution of this should be a solution of that. So these two equations are supposed to be completely equivalent. What's required of this transformation for the solutions to be completely equivalent? Again, let me give you an example. What if instead of this transformation x minus 10 from this equation, I would have another transformation of this type, x minus 10 squared? It's a transformation. It's a function which is defined on the same set of real numbers. Now, if I define this function to the left part of the equation, so instead of x, I will substitute x plus 10. I will have on the left x squared, right? x minus x minus plus 10 minus 10 squared. On the right, I will have what? I will have 13 minus 10, which is 3 squared 9. So that's my transformed equation. Well, I can say, hey, this is an easy equation. I know that the square of 3 is 9. But well, the square of minus 3 is also 9. So this equation has two different solutions, 3 and minus 3. Original equation, obviously, has only 3. Minus 3 doesn't fit. So this transformation is not good. This transformation changes the equation to something which is not equivalent. So somewhere, somehow, I have to generalize the concept of transformation, which transforms my original equation into another one, which is completely equivalent. And here's how it's done, how this generalization is done. Let's consider this function t of x. What I'm stating right now is that if t of x is representing a function which is one-to-one correspondence between its arguments and its values, one-to-one correspondence, it means that I can always not only go from argument to a value, but also from the value back to the same argument, then the function t of x is a valid transformation for any equation, actually. So only functions which represent one-to-one correspondence between arguments and values fit to our transformations which we can use to solve equations. Now, what it means is the following. I can take any value of this function. And what I'm saying is that I can always find a regional argument of this function which resulted in this value if applied the function t of x. What it means from another standpoint is that I have another function which usually is symbolically represented t to the power of minus 1. It's just a symbolic, has nothing to do with power. It's a symbolic representation of inverse function. So the function t minus 1 of x actually works this way. It's defined where the t of x has values, which means here. And its values are where the arguments of the original function is. And it works in a completely reverse fashion. So the arrows, it's the same arrows but directed differently to the opposite side. So these two functions are inverse to each other. And all those functions t of x, which have inverse function, are allowed to be called invariant transformations of our equations. Function x minus 10 is obviously inversible. The inverse function is x plus 10. Function x minus 10 squared is obviously not inversible because there are always two different values of x of argument x for any value of this function. For instance, to get to 9, I can have either x equals to 13. So it will be 3 squared is equal to 9. Or I can get 7, 7 minus 10 minus 3 squared again 9. So I have two different arguments, 7 and 13, which are transformed by this function into 9. And if I have two different arguments which are transformed into the same value, then there is no inverse, obviously, because I cannot say what's the inverse function of 9. It can be either 7 or 13. And if I have two different values, it's not a function anymore. Function is always something which you can definitely say what exactly is the result of this function. And reverse function does not really exist in this particular case. So when we are talking about invariant transformation, we are talking about those functions, t of x, defined on the codemain of our original function f, which have inverse. Now what I'm saying is that applying this transformation transforms our original equation like this to equivalent. Now, if I apply my transformation t on the left bot, I will have this. On the right part, I have this. So if my original equation is this, and transformation is x minus 10, for instance, then I apply x minus 10 to this. And I get x plus 10 minus 10, which is x. And on this, 13 minus 10 will be 3. And that's how I get x equals to 3. Using the transformation t of x equals x minus 10. That's an example. Now, let me prove that this particular equation is exactly equivalent to the original one, because that's the purpose of this transformation. I have to transform into something simpler. But that should be equivalent. OK, so that's what we're getting into right now. We have to prove that these two equations are completely equivalent, which means every solution of this is a solution of this. And vice versa. If I have a solution of this equation, then it will be a solution of that equation. All right, let's consider that A is a solution of original equation. That means that f of A is equal to d. OK, now, what it means is this is A is an element of the domain of function f. f of A is an element of a column A. And v is also an element of column A. If I have two different elements of the column A, I can always apply function g. But this is exactly the same element. So applying the function t to the same argument will obviously give me the same value. So I can say that t from f of A is obviously equal to t of b, because f of A and b are two equal arguments. And that's why the function results in the same value. So the direct theorem is very simple. It's trivial, actually. What's important is to convert it. So let's go back. This is not even a theorem. This is just a joke. Now, the real one is, what if A is a solution of this equation? So I know that g of f of A equals to g of b. So that means that the A is the solution of this equation. And here, the invariant transformation, the property of invariant transformation to always have inverse, that's where it's very important. And that's where it plays the most important role. Here's half. Now, I know that A is a solution. So these are two identical elements of the codemy. And I also know that t has an inverse function, which we call t of minus 1. So if I will apply t minus 1 to t of f of A, I will have exactly the same as t minus 1 applied to t of b. Well, since these are identical, then applying a function, t to the minus 1, which is inverse function to t, will give me the same values. But now, let's think about what this represents. Well, f of A is certain element of the codemy of A. t transforms it to something. But I know that t minus 1 is inverse to t, which means it returns back from the value to the argument. So again, if this is my codemy, function t goes this way, function t minus 1 goes back. That's the definition of the inverse function. It's defined from here to here. And the result of t minus 1, the inverse function to t, is the original argument from which we started. So by definition of the inverse function, left part is equal to f of A. And the right part, for the same reason, by definition of the inverse function is b. That actually should be very clear. The fact that inverse function, inverse t of t of b, is b, basically by definition of the inverse function. And we have assumed that inverse function exists for this transformation t. So from existence of this inverse function, we have concluded, basically, that if A is a solution of this transformed equation, then A is a solution of the original equation. So we have proved right now that both equations have exactly the same set of solutions. If solution is here, then it's here. Or if it's here, then it's there. So that basically kind of explains what we do when we try to solve equations using our, I would say, digital ways which everybody is learning at school. We know that we can subtract, for instance, the same number from both sides of the equation, like in this particular case. We can subtract 10, we are saying. Well, what does it mean we can subtract 10? It means we can apply an invariant transformation of type t of x equals x minus 10. If we apply this transformation to this equation, we will get x equals 3. And that's basically a trivial solution of this thing. And this transformation is obviously reversible, and the reversible function is x plus 10. One is subtract 10, another is else 10. And obviously, these two transformations are inverse to each other. Because think about this, t minus 1 of t of x. I was saying that by definition it should give x, right? Well, let's just think about it. From t of x, I can substitute x plus 10, sorry, minus 10. But t minus 1 of this means this plus 10. Obviously, I get x as a result. That's what it means that the functions are inverse to each other. So basically, again, what I'm saying is that the rules which we have learned in school that we can subtract the same number for both sides of equation are actually a particular representation of this invariant transformation of this type. Now, another rule. For instance, we have an equation 2x equals 8. Well, everybody knows we can divide both sides of the equation by some number, which is not equal to 0, obviously. If you divide it by 2, we will get x equals 4. What does it mean from the general standpoint? It means that we apply transformation equals to 1 half of x. So if we apply this transformation to the left part, we will have 2 times 1 half of x, which is x. And on the right, 8 applied to the paper. Now, what's the inverse function in this ace? Obviously, it's 2x. If you apply first this and then that, you will return back to x. First from x to 1 half of x, then multiply by 2 will be x again. So both sides of equation can be multiplied or divided by not equal to 0, or multiplied by not equal to 0 by the same number. Oh, by the way, why is it not 0? Why can I say that I can multiply both sides of the equation by 0? Well, for obvious reason. If function is this 0, then there is no t minus 1 of x. There is no inverse function. There is no such thing as a function which returns back to the original. Because if you take, for instance, value of 2, for instance, you get 0. So from 2, you get 0. But if you get value of 22, it will also give you 0. So this is not a one-to-one correspondence. t of x does not represent a one-to-one correspondence. And that's why many different, actually infinitely many different value arguments are resulting in the same value. So there is no way I can go back. I don't know from 0 where the original argument came from. So that's why we cannot multiply, and obviously cannot divide, by 0 as an invariant transformation. OK, what if you have an equation of a different sort? Let's say x squared equals to 4. Well, you know that 2 and minus 2 both are solutions to this particular equation, right? So let's apply a transformation, which is a mistake in this particular case, and extract the square root from both sides. Well, I can say that square root of x2 is equal to square root of 4 x equals 2. Is it right? No, it's absolutely incorrect. It's absolutely wrong. Why? Because the square root is not an invariant transformation in this particular case. And as a result of applying a non-invariant transformation, we can lost one solution, which is minus 2. This equation has only solution x equals 2. This solution obviously has 2 and minus 2. So by applying non-invariant transformation, we can lost one of the roots, one of the solutions of the equation. So square root is not an invariant transformation. How about cubicle root? Well, actually it is. And here is why. Example 5 on that graph. Y equals cubicle root of x, which is the same as x to the minus 1, 1, 3, power of 1, 1, 3, has a graph which looks like this. This is 1. This is 1 minus 1. So this is a graph. And it's very easy to see from the graph that it represents a one-to-one correspondence between arguments. These are arguments on the x-axis and values on the y. Because for every x, I have one and only one y. And for every y, I have only one x. So that's one-to-one correspondence. And that's very, very important. And square root is not such a thing. Because if this is y is equal to x, then it's very important, actually. For positive y, this function is defined. And you can definitely get the positive value of square root of it. But again, if you do the negative part, this would also be exactly the same thing. Like this is 4 on y. This is minus 2. And this is 2. Both will give you the actual, I shouldn't say it this way. We're talking about function which looks like this. Then we can go from y back to x. From x we square it, we get y. From y, we go down by using x is equal to square root of y. So the shape is like this. But in any case, whatever the shape is, the same y has basically two different value of x which correspond to this function. And since we have two different values, we don't have one-to-one correspondence. So in this particular case, we do have a one-to-one correspondence. And that's why this function can be applied as an invariant transformation. And this function cannot. This is not a good one. Anyway, there are many different examples of invariant transformations. And basically, now I can answer the question, how to solve equations. OK, this is the general answer. You have to try to find invariant transformations which will transform your original equation into something simpler. And the simpler one can probably be solved. If you can transform it down to something like x is equal to 3, then this basically represents a solution to your original equation. Sometimes it's easier to solve equations using these invariant transformations by basically breaking the domain into different parts. And in certain parts, use one particular transformation. And in another part, use another. And I will just exemplify in this particular case of this equation. How can I solve these equations without actually using the square root? I said that we cannot use the square root. But here's how. I know the domain of this is all real numbers, right? So let's just divide this domain into two halves. One is positive numbers, and another is negative numbers. If x is only positive numbers, then function is invariant transformation. If x is only the positive number, y is a positive number, and we can always square y to get the positive number, and we will get x. And there is no problem with this. Now, in the negative part, we can always apply a transformation minus x. So let's divide. If x greater than 0, or if it doesn't matter, we apply this, and we get x is equal to 2. We're talking about positive numbers only. Now, in the negative numbers, if x is negative, then what I can say is I can apply square root of x, of minus x, and what will I have? If x is not, that's probably not exactly correct. I think let's just use a different function. Let's use this function. Here, this transformation. Square root of x square is x, but now we have a minus, right? Here. So minus x is equal to 2. That's what we'll do. x square goes to this, and square root of x square gives you x, and this minus in front will give you this. Or from this, we can multiply both by minus 1. We get x equal to minus 1. So now, since we have divided our domain into two parts and used two different invariant transformations in each part, then we are OK. And we have two solutions, and we have not lost things. Well, I was trying to be as smooth as possible. There are certain things which I really had to think twice about. Well, but that just proves that this is not like other things from the very beginning. And as long as you understand that invariant transformation is the generalized method to solve equations, that's great. And a technique of dividing the domain into different parts where you can define different invariant transformations, that's the proper way of solving equations of this type where you don't really have an easy invariant transformation which can be applied to an entire domain. Well, that's it for today, and thank you very much.


Going on everyone Sam here late in sports cards rip in one box of 22 a panini origins football hobby for Greg B It's good luck here Greg see what we got here for event my man We've got Matt Ryan to 75 for the Colts old beam that Ryan Aaron Donald to 199 for the Rams That's when they're a let We've got Devonte Adams Gabriel Davis First hit is gonna be a three colored patch 81 out of 99 James Cook for the bills nice one there and it works We've got Aidan Hutchinson on card rookie Otto for the Lions nice one there. He's so good So good. It's unfair. How good he is man Might be Then we've got a Samir White rookie Jersey Otto that is going to the Raiders congrats on that Raiders They are yeah I'll do it for your break there Greg congrats on the hits man. We'll get them right out to you. Thanks as always buddy