/js/src/jit-test/tests/basic/createMandelSet.js
https://github.com/wisec/DOMinator · JavaScript · 242 lines · 199 code · 22 blank · 21 comment · 29 complexity · 431fe0887481ebbe576e77bddeadb6c7 MD5 · raw file
- // |jit-test| slow;
- // XXXbz I would dearly like to wrap it up into a function to avoid polluting
- // the global scope, but the function ends up heavyweight, and then we lose on
- // the jit.
- load(libdir + "mandelbrot-results.js");
- //function testMandelbrotAll() {
- // Configuration options that affect which codepaths we follow.
- var doImageData = true;
- var avoidSparseArray = true;
- // Control of iteration numbers and sizing. We'll do
- // scaler * colorNames.length iterations or so before deciding that we
- // don't escape.
- const scaler = 5;
- const numRows = 600;
- const numCols = 600;
- const colorNames = [
- "black",
- "green",
- "blue",
- "red",
- "purple",
- "orange",
- "cyan",
- "yellow",
- "magenta",
- "brown",
- "pink",
- "chartreuse",
- "darkorange",
- "crimson",
- "gray",
- "deeppink",
- "firebrick",
- "lavender",
- "lawngreen",
- "lightsalmon",
- "lime",
- "goldenrod"
- ];
- const threshold = (colorNames.length - 1) * scaler;
- // Now set up our colors
- var colors = [];
- // 3-part for loop (iterators buggy, we will add a separate test for them)
- for (var colorNameIdx = 0; colorNameIdx < colorNames.length; ++colorNameIdx) {
- //for (var colorNameIdx in colorNames) {
- colorNameIdx = parseInt(colorNameIdx);
- colors.push([colorNameIdx, colorNameIdx, colorNameIdx, 0]);
- }
- // Storage for our point data
- var points;
- var scratch = {};
- var scratchZ = {};
- function complexMult(a, b) {
- var newr = a.r * b.r - a.i * b.i;
- var newi = a.r * b.i + a.i * b.r;
- scratch.r = newr;
- scratch.i = newi;
- return scratch;
- }
- function complexAdd(a, b) {
- scratch.r = a.r + b.r;
- scratch.i = a.i + b.i;
- return scratch;
- }
- function abs(a) {
- return Math.sqrt(a.r * a.r + a.i * a.i);
- }
- function escapeAbsDiff(normZ, absC) {
- var absZ = Math.sqrt(normZ);
- return normZ > absZ + absC;
- }
- function escapeNorm2(normZ) {
- return normZ > 4;
- }
- function fuzzyColors(i) {
- return Math.floor(i / scaler) + 1;
- }
- function moddedColors(i) {
- return (i % (colorNames.length - 1)) + 1;
- }
- function computeEscapeSpeedObjects(real, imag) {
- var c = { r: real, i: imag }
- scratchZ.r = scratchZ.i = 0;
- var absC = abs(c);
- for (var i = 0; i < threshold; ++i) {
- scratchZ = complexAdd(c, complexMult(scratchZ, scratchZ));
- if (escape(scratchZ.r * scratchZ.r + scratchZ.i * scratchZ.i,
- absC)) {
- return colorMap(i);
- }
- }
- return 0;
- }
- function computeEscapeSpeedOneObject(real, imag) {
- // fold in the fact that we start with 0
- var r = real;
- var i = imag;
- var absC = abs({r: real, i: imag});
- for (var j = 0; j < threshold; ++j) {
- var r2 = r * r;
- var i2 = i * i;
- if (escape(r2 + i2, absC)) {
- return colorMap(j);
- }
- i = 2 * r * i + imag;
- r = r2 - i2 + real;
- }
- return 0;
- }
- function computeEscapeSpeedDoubles(real, imag) {
- // fold in the fact that we start with 0
- var r = real;
- var i = imag;
- var absC = Math.sqrt(real * real + imag * imag);
- for (var j = 0; j < threshold; ++j) {
- var r2 = r * r;
- var i2 = i * i;
- if (escape(r2 + i2, absC)) {
- return colorMap(j);
- }
- i = 2 * r * i + imag;
- r = r2 - i2 + real;
- }
- return 0;
- }
- var computeEscapeSpeed = computeEscapeSpeedDoubles;
- var escape = escapeNorm2;
- var colorMap = fuzzyColors;
- function addPointOrig(pointArray, n, i, j) {
- if (!points[n]) {
- points[n] = [];
- points[n].push([i, j, 1, 1]);
- } else {
- var point = points[n][points[n].length-1];
- if (point[0] == i && point[1] == j - point[3]) {
- ++point[3];
- } else {
- points[n].push([i, j, 1, 1]);
- }
- }
- }
- function addPointImagedata(pointArray, n, col, row) {
- var slotIdx = ((row * numCols) + col) * 4;
- pointArray[slotIdx] = colors[n][0];
- pointArray[slotIdx+1] = colors[n][1];
- pointArray[slotIdx+2] = colors[n][2];
- pointArray[slotIdx+3] = colors[n][3];
- }
- function createMandelSet() {
- var realRange = { min: -2.1, max: 1 };
- var imagRange = { min: -1.5, max: 1.5 };
- var addPoint;
- if (doImageData) {
- addPoint = addPointImagedata;
- points = new Array(4*numCols*numRows);
- if (avoidSparseArray) {
- for (var idx = 0; idx < 4*numCols*numRows; ++idx) {
- points[idx] = 0;
- }
- }
- } else {
- addPoint = addPointOrig;
- points = [];
- }
- var realStep = (realRange.max - realRange.min)/numCols;
- var imagStep = (imagRange.min - imagRange.max)/numRows;
- for (var i = 0, curReal = realRange.min;
- i < numCols;
- ++i, curReal += realStep) {
- for (var j = 0, curImag = imagRange.max;
- j < numRows;
- ++j, curImag += imagStep) {
- var n = computeEscapeSpeed(curReal, curImag);
- addPoint(points, n, i, j)
- }
- }
- var result;
- if (doImageData) {
- if (colorMap == fuzzyColors) {
- result = mandelbrotImageDataFuzzyResult;
- } else {
- result = mandelbrotImageDataModdedResult;
- }
- } else {
- result = mandelbrotNoImageDataResult;
- }
- return points.toSource() == result;
- }
- const escapeTests = [ escapeAbsDiff ];
- const colorMaps = [ fuzzyColors, moddedColors ];
- const escapeComputations = [ computeEscapeSpeedObjects,
- computeEscapeSpeedOneObject,
- computeEscapeSpeedDoubles ];
- // Test all possible escape-speed generation codepaths, using the
- // imageData + sparse array avoidance storage.
- doImageData = true;
- avoidSparseArray = true;
- for (var escapeIdx in escapeTests) {
- escape = escapeTests[escapeIdx];
- for (var colorMapIdx in colorMaps) {
- colorMap = colorMaps[colorMapIdx];
- for (var escapeComputationIdx in escapeComputations) {
- computeEscapeSpeed = escapeComputations[escapeComputationIdx];
- assertEq(createMandelSet(), true);
- }
- }
- }
- // Test all possible storage strategies. Note that we already tested
- // doImageData == true with avoidSparseArray == true.
- escape = escapeAbsDiff;
- colorMap = fuzzyColors; // This part doesn't really matter too much here
- computeEscapeSpeed = computeEscapeSpeedDoubles;
- doImageData = true;
- avoidSparseArray = false;
- assertEq(createMandelSet(), true);
- escape = escapeNorm2;
- doImageData = false; // avoidSparseArray doesn't matter here
- assertEq(createMandelSet(), true);
- //}
- //testMandelbrotAll();