Skip to content

A program that approximates the area of the Mandelbrot set

Notifications You must be signed in to change notification settings

hsingtism/mandelbrot-area

Repository files navigation

A program that approximates the area of the Mandelbrot set

This is a program that approximates the area of the Mandelbrot set using a variety of methods.

  • monte-carlo.c uses the monte-carlo method
    • The random coordinates are generated by the xorshift128plus PRNG function.
    • Multiple instances can be ran independently in parallel, stopped at any time, and the results can be averaged together (should be weighted).
    • ensure that the PRNG receive different initial seeds
  • simple-grid.c pick random points within a grid
    • Some randomness is involved, but random values are generated within a grid which results in a more uniform distribution.
    • Values are only usable and outputted after an entire grid scan, this can take different amount of time depending on the grid size.
    • The grid size is defined by GRID_SIZE at the beginning.
    • ensure that the PRNG receive different initial seeds

Starting parameters (the #defines in mandelbrot-area.h)

change before compilation

  • dwellLimit - unsigned long - the maximum number of times a number will be iterated and checked for divergence, convergence, and cyclic orbits before it is deemed as UNDECIDED
  • C_EQUIVALENCE_THRESHOLD - double - iterations with points closer than this are returned as convergence
  • O_EQUIVALENCE_THRESHOLD - double - orbits where values are closer than this are considered a member
  • updateInvl - unsigned long long - the number of values that will be checked until an update message is printed
  • S_SEED - unsigned long long - this number will be xor'ed with the system time to generate a seed
  • FILE_OUTPUT - int when used, actually boolean - 1 to enable logging to file, 0 to disable.

Random generation

This program heavily relies on random so this is important. This section explains where the random values come from.

  • Random doubles within range are returned by _22() and _01(), all these function relies on xorshift128plus to generate its mantissa.
  • xorshift128plus should be sufficient for this usage
  • On unix systems the PRNG is seeded by system time, /dev/urandom, and S_SEED
  • On windows systems, the PRNG is only seeded by time(), and S_SEED. This should be good enough due to the chaotic behavior of the function.
    • IF YOU ARE RUNNING MULTIPLE INSTANCE ON WINDOWS, MAKE SURE THEY ARE NOT STARTED WITHIN 1 SECOND OF EACH OTHER
  • After the initial seeding, the function is called 128 times to scramble the states up
  • The states are xor'ed with the aforementioned seed sources every time a status message is displayed

Another PRNG can be used in place of this one as long as it returns 64 bits

Compiling

Using your favorite compiler, compile your choosen file and mem-func.c

Example: using gcc to compile the Monte Carlo file with optimization

  • gcc .\monte-carlo.c .\mem-func.c -O3 -o monte-carlo

Output

Output is printed to standard output, it is also written into log.txt. Multiple instances of the program (when ran in the same directory) will write to the same file, each instance is identified by its start time provided by time.h

Output is formatted as follows

  • When an instance is started - instance 1645383166 started is printed (or whatever the time is) followed by a row of keys
  • When an update is printed (see updateInvl), a row of comma delimited data is printed in the format of timestamp, instance, member, not member, undecided; the number of computed area is simply: 16 * (member + (1 or 0 multiplied by) undecided) / (member + undecided + not member)
  • When membership of a value cannot be determined (dwell limit reached), the number and its exact floating point bit representation is printed

Analysis of output: analyze.js

  • analyze.js is provided for basic calculations and analysis
  • paste the log file as an array of strings into data to the file and execute it with your favorite javascript interpreter
  • setting dataI falsey and dataP truthy reads data from log.txt. THIS ONLY WORKS FOR simple-grid DATA; THIS ONLY WORKS FOR simple-grid DATA; THIS ONLY WORKS FOR simple-grid DATA
  • results will be printed into console

Output of analyze.js

  • The first table is individual analysis of each instance
    • id is the instance id, or the time the instance was started
    • computationTime is the amount of time from the instance's start to the time of the output log
    • mem, notmem, and undeci are member, not a member, and undecided
    • totalTested is the number of points tested
    • computationRate is the average rate of calculation
    • diffToAvgHLog10 and diffToAvgLLog10 are the common log of the difference from the instance's value to the average value among all instances†
    • dBAHLog10 and dBALLog10 are the common log of the difference from the instance's value to the best existing average which by default is 1.5065918849±0.0000000028 by Thorsten Förstemann. This can be changed.†
    • † = the sign of the difference is appended to show potential bias
  • Table 2 shows sums of data along with its common log
    • instanceNum is the number of instances or log files
    • totalComputationTime is the total runtime among all instances
    • totalTested, totalMember, totalNonMember, and totalUndecided are the sum of respective values among all instance
  • Table 3 shows the standard deviation and its common log
    • Keep in mind that floating point might do weird stuff
  • Table 4 shows the estimated area and information about it
    • high is the estimate including undecided, low does not include undecided
    • difference is the difference between high and low, and diffLog10 is its common log
    • the next 4 line are the difference of the calculated value to the best existing estimate and its common log