Jump to my Home Page Send me a message Check out stuff on GitHub Check out my photography on Instagram Check out my profile on LinkedIn Check out my profile on reddit Check me out on Facebook

Mitch Richling: Collatz Fractal

Author: Mitch Richling
Updated: 2024-10-31

skinny_25.png

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:

collatz_03_20.png

4. References

Check out the fractals section of my reading list.

All the code used to generate everything on this page may be found on github.