Mitch Richling: Collatz Fractal
Author: | Mitch Richling |
Updated: | 2024-10-31 |
Table of Contents
1. Introduction
The Collatz conjecture is a famous unsolved math problem. In studying the Collatz conjecture, mathematicians have defined the Collatz map and it's smooth continuation:
\[f(z)=\frac{1}{2}z\cos^2\left(\frac{\pi}{2}z\right)+\frac{3x+1}{2}z\sin^2\left(\frac{\pi}{2}z\right)\]
Of course, whenever fractal-heads see a smooth complex function, they want to iterate the thing and make pretty pictures. :)
2. Algorithms
We render the Collatz Fractal using the \(L\) function just like we did with the Mandelbrot Set. The general idea is to map an array of pixels making up the raster image to a rectangular region of the complex plane, and color each pixel of the image based upon a color scale for the computed value of the \(L\) function. Coding up this idea leads to the following C++ program:
#include "ramCanvas.hpp" int main(void) { std::chrono::time_point<std::chrono::system_clock> startTime = std::chrono::system_clock::now(); const int NUMITR = 164; const int IMXSIZ = 7680/2; const int IMYSIZ = 7680/2; //mjr::ramCanvas3c8b theRamCanvas(IMXSIZ, IMYSIZ, -3.75, 3.75, -3.75, 3.75); // 56 centered 0+0i //mjr::ramCanvas3c8b theRamCanvas(IMXSIZ, IMYSIZ, -0.99-0.15, -0.99+0.15, -0.15, 0.15); // 28 centered near 1+i mjr::ramCanvas3c8b theRamCanvas(IMXSIZ, IMYSIZ, -0.99-0.03, -0.99+0.03, -0.03, 0.03); // 28 same, zoomed in for(int y=0;y<theRamCanvas.getNumPixY();y++) { for(int x=0;x<theRamCanvas.getNumPixX();x++) { std::complex<double> z = theRamCanvas.int2real(x, y); int count = 0; while((std::norm(z)<1e10) && (count<=NUMITR)) { z = 0.25 * (2.0 + 7.0*z - (2.0 + 5.0 * z) * std::cos(z * std::numbers::pi)); count++; } if(count < NUMITR) theRamCanvas.drawPoint(x, y, mjr::ramCanvas3c8b::colorType::csCCsumRGB::c(static_cast<mjr::ramCanvas3c8b::csIntType>(count*28))); } } theRamCanvas.writeTIFFfile("collatz.tiff"); std::chrono::duration<double> runTime = std::chrono::system_clock::now() - startTime; std::cout << "Total Runtime " << runTime.count() << " sec" << std::endl; }
The above program will generate this picture: