- Overview
- executable, Eclipse and Maven projects
- executable, Eclipse and Maven projects
- executable, Eclipse and Maven projects
- executable, Eclipse and Maven projects
- executable, Eclipse and Maven projects
- executable, Eclipse and Maven projects
The option provided by the JLayer Framework to have the method of a unit class executed in parallel on the available processor cores only offers an advantage if the execution of this method firstly has no side effects and secondly takes a lot of time.
These requirements are basically met if one wants to visualize the Mandelbrot set, and with the help of the present Mandelbrot program it is possible to compare the loop implementation with the parallel implementation. In this sample program, the linking of objects is irrelevant.
In order to calculate the color of a pixel in the image (locally),
the overall size of the image and the position of the pixel must be known.
In addition, a maximum limit for an iteration to be performed must be specified.
All these things are reflected in the MandelbrotUnit
class code as follows.
In addition to the static fields width
, height
and maxIterations
,
you find the static field palette
, which is used to store RGB values,
and all these fields are set using the static setGlobalParams()
method.
Layer field index
has the annotation @LayerField(isIndex = true)
and this ensures that the correct index is set automatically when wrapping object arrays
of type MandelbrotUnit
, and layer field rgbValue
is used to store the computed color.
@LayerUnit
public class MandelbrotUnit { private static int width, height; private static int maxIterations; private static int[] palette;@LayerField(isIndex = true)
int[] index;@LayerField
int rgbValue; static void setGlobalParams(int width, int height, int maxIterations) { MandelbrotUnit.width = width; MandelbrotUnit.height = height; MandelbrotUnit.maxIterations = maxIterations; palette = new int[256]; for (int i = 0; i < 256; i++) palette[i] = Color.getHSBColor(i/255F, 1, 1).getRGB(); } private int countIterations(int row, int col) { double xmin, xmax, ymin, ymax; xmin = -1.6744096740931858; xmax = -1.674409674093473; ymin = 4.716540768697223E-5; ymax = 4.716540790246652E-5; double x, y; double dx, dy; dx = (xmax-xmin)/(width-1); dy = (ymax-ymin)/(height-1); y = ymax - dy*row; x = xmin + dx*col; int count = 0; double xx = x; double yy = y; while (count < maxIterations && (xx*xx + yy*yy) < 4) { count++; double newxx = xx*xx - yy*yy + x; yy = 2*xx*yy + y; xx = newxx; } return count; } private int getRGB(int count) { if (count == maxIterations) return 0; else return palette[count%palette.length]; } private void setRgbValue() {int row = index[0];
int col = index[1];
int count = countIterations(row, col); rgbValue = getRGB(count); }@LayerMethod
void setRgbValue_LOOP(){ setRgbValue(); }@LayerMethod(runtimeMode=RuntimeMode.FORKJOIN)
void setRgbValue_PARALLEL(){ setRgbValue(); } }
At the bottom you find two annotated methods setRgbValue_LOOP()
and setRgbValue_PARALLEL()
that actually cause the setRgbValue()
method to loop or run in parallel.
Note that setRgbValue()
needs to know its position - row
and col
-
which is passed as parameter
to method countIterations()
, the execution of which
is the brunt of the calculation.
The MandelbrotNet
class executes the color calculations
in a loop or in parallel and also establishes a connection to the graphic display.
The parts of the code that depend on the JLayer framework
are color coded.
At the top are the definitions of the global parameters mentioned above,
the declaration of an array of MandelbrotUnits
and its associated wrapper object mandelbrotLayer
,
and the declaration of the mandelbrotImage
field
that serves as the interface to the graphical representation.
Next, in method createNetwork()
, everything is initialized.
public class MandelbrotNet { int width = 1600; int height = 1200; int maxIterations = 10000; MandelbrotUnit[][] mandelbrotArray = null;Layer_MandelbrotUnit_ mandelbrotLayer = null;
BufferedImage mandelbrotImage = null; void createNetwork() { MandelbrotUnit.setGlobalParams(width, height, maxIterations); mandelbrotArray = new MandelbrotUnit[height][width]; for(int row = 0; row < height; row++) { for(int col = 0; col < width; col++) { mandelbrotArray[row][col] = new MandelbrotUnit(); } }mandelbrotLayer = new Layer_MandelbrotUnit_(mandelbrotArray);
mandelbrotImage = new BufferedImage(width,height,BufferedImage.TYPE_INT_ARGB); Graphics g = mandelbrotImage.createGraphics(); // fill image with gray g.setColor(Color.LIGHT_GRAY); g.fillRect(0,0,width,height); g.dispose(); } private void updateImage() { for(int row = 0; row < height; row++) { for(int col = 0; col < width; col++) {mandelbrotImage.setRGB(col, row, mandelbrotLayer.rgbValue.get(row, col));
} } } void setRGB_LOOP() {mandelbrotLayer.setRgbValue_LOOP();
updateImage(); } void setRGB_PARALLEL() {mandelbrotLayer.setRgbValue_PARALLEL();
updateImage(); } }
The two methods setRGB_LOOP()
and setRGB_PARALLEL()
at the end
trigger the sequential or parallel calculation of the colors and afterwards update the graphical interface.