 All right, so learning, we do it every day, but today I'm gonna share with you what was probably one of the best, if not the best learning experience in my entire life. It all revolves around this image over here. This is a Newton fractal, or a Newton-Raphson method fractal, and if you know anything about fractals, you probably know where I'm going with this, you know where this comes from, and you can probably skip this entire next part of the video. But long story short, it's this function, X minus P of X divided by P dash of X. P of X is any polynomial of any order, and X itself is just a random guess on the complex plane, which is what this fractal is drawn on, like most fractals. Basically, P of X has four roots in the complex plane. They're around these four locations. And what we do for every single pixel is we run the Newton-Raphson equation on it, a certain amount of times, maybe a hundred times or 20 times, until we see which root it lands nearest to. Now we color each root and each pixel according to this, and when we pull all those pixels back, we get this image, which is very fancy look. Now if you wanna know more about this method, you wanna know more about where this comes from and why this is true, you should watch this video by Three Blue and Brown, where he runs through how this actually came to be and how Newton's method is very, very useful for finding the roots of polynomials. However, I just wanna focus on the programming aspect and the logistics of actually drawing an image like this, because that's what really had me caught up for like a month, trying to figure out how to do something like this. I would like to structure this video in the form of tips of general pointers that I give to people who are looking into mathematics or science or programming for fun. The first big tip I give is to set an appropriate scope, because too many people tend to either set too much work for themselves or set too little work for themselves and end up unsatisfied with the end result. In my case, it was the latter. Remember that p dash of x from the Newton-Raphson equation? Well, I wanted a function in my program that could genuinely take the data from p of x and then figure out the real derivative function instead of just estimating it to an appropriate degree. Doing this estimation of the derivative by using a sufficiently small change in x and calculating the change in y isn't only computationally less intensive, it's less rough on the computer, but it also takes less time to program. And if I actually went through and tried to make a complicated system to calculate the real proper derivative, then I would have probably wasted way too much time on that and not on making this very pretty picture. So once that got thrown out the window, I just decided to use a traditional equation that you can have in a function. And as far as the Newton-Raphson part of the program was concerned, it was just smooth sailing from then on. The next big tip I have for people doing science or math stuff or especially programming is to try to be both efficient and creative with your solutions. One of my big problems when I first approached this issue was how exactly do you create an image? What do I do? Do I need to plot all the points? Do I need to make some kind of image file? How am I going to format that? How is that going to look? How am I gonna assign the colors? That's surprisingly difficult to come up with and there's so many options, many of them being, quote unquote, right answers. And the trouble was picking one that was the most appropriate for this problem. Originally, I used Pi plot lib, which if you don't know is a library for Python that lets you plot stuff on a graph, which probably seems very useful in this situation. However, this really did improve to be true. Not only did I have to calculate the position of every single item in the array, which was unnecessary overhead in the program, but Pi plot lib itself is super slow when you're dealing with lots of points. So clearly the far more efficient and better method to go with here was to create an image. More specifically, this led me down the road to discovering all the various creative image formats that exist and ended up settling for something called PGM. Now, if you don't know what a PGM is, essentially you can declare the size and the width and the grayscale of an image and then just have zero, one, two, three, four, whatever, define the level of lightness for the pixels on your image. This is a very simple way of having an image file format that you can write to and create grayscale images. This was exactly what I was looking for and I instantly got to work making a system that could write to these images. So in summary, most of the tools that you probably need, the tools that are best for the job tend not to be in front of you. You have to go out there and research and be creative until you find exactly what you're looking for. All right, so now that I have the origins of our fractal, the Newton-Raphson equation and the endpoint, which is the image file format, I need to figure out how to glue these things together in Python. So it all starts with considering each pixel being a complex number. It's a pretty simple 2D visualization where every single X coordinate is the real part and every single Y coordinate is the imaginary part of this head complex number. You then take this number and put it into the Newton-Raphson method and repeat after a few times and then see which route it lands closest to after a limited amount of permutations. After doing this over and over again with every single possible pixel on the grid, you then compare its value with one of the roots, which either you know or you can figure out by looking at your results. Depending on which route it lands closest to and the order in which you put the roots, which is arbitrary, you can calculate the color of the pixel by simply picking a number between zero and the order of the polynomial minus one. The color can be equal to the index of the root that it's closest to if the roots aren't a specific array. Remember the radius we used before? Well, we can use that in the calculation to figure out the resolution of our picture and we can also output the color depth by using the order minus one. And once all this data, including the actual pixel data for each individual point on the graph is outputted to an image, we finally get our sought after Newton's fractal. But the thing is, is that I'm nowhere near done with this. That's the last lesson I wanna give to you about learning is that you're probably never gonna be finished with what you're learning. There's always more to do. There's always more to figure out. And there's always more things to break for you to fix later. This program already has a few problems. Like for example, if you increase the radius past 100 or so, it starts taking a long time for these images to render. Now that might just be up to Python being very slow, but it's also just poor programming practice in general. I mean, a lot of the pixels here are the exact same color and that can probably be made far more efficient. So long story short, the real point I wanna get across to this video is that when you learn for yourself, you tend to not only develop your knowledge, but also your skills to learn in the future. I now know how to do a lot more stuff in Python. I know a lot more stuff about math, just because I spent a few months figuring out this Newton-Raphson thing. It was fun to do. It was educational, but most importantly, we got some really pretty pictures out of it. So yeah, I've been Denshi. That was learning, programming and fractals. Goodbye.