1

While implementing the mandelbrot set using java, I found that the rendering time of the program is ridiculously slower than other programs.

public class FractalFormula {
    private Complex[] referenceOrbit = new Complex[0];

    private int skippedIterations;
    private Complex calcBn;
    private void approximationData(double dcMax) {

        List<Complex> calcBnList = new ArrayList<>();
        double limit = Math.sqrt(0.5 / dcMax);
        
        int skipCount = 0;
        Complex cbn = Complex.ZERO;

        for (int i = 0; i<referenceOrbit.length; i++) {
            Complex complex = referenceOrbit[i];
            Complex doubledComplex = complex.multiply(2);
            Complex pbn = cbn;
            cbn = cbn.multiply(doubledComplex).add(Complex.ONE);
            double rb = cbn.radius2();

            if (rb >= limit * limit) {
                calcBnList.add(pbn);
                skippedIterations = skipCount;
                calcBn = pbn;
                return;
            }else{
                skipCount++;
            }

        }
    }


    // Runs only once before "iterate()"
    public void calculateReferenceOrbit(BigComplex c, MathContext floorMode, int maxIteration, double dcMax) {

        List<Complex> referenceOrbit = new ArrayList<>();
        int iteration = 0;
        BigComplex z = BigComplex.ZERO;
        referenceOrbit.add(z.normalValue());
        while (z.normalValue().radius2() < 4 && iteration < maxIteration) {
            z = z.multiply(z, floorMode).add(c, floorMode);
            Complex nz = z.normalValue();

            iteration++;
            referenceOrbit.add(nz);
        }
        this.referenceOrbit = referenceOrbit.toArray(Complex[]::new);
        approximationData(dcMax);

    }

    
    // it returns the double value of iteration
    // Performs the corresponding action on all pixels
    public double iterate(Complex[] referenceOrbit, double maxIteration, Complex dc) {
        
        int iteration = skippedIterations;
        int refIteration = skippedIterations;
        int maxRefIteration = referenceOrbit.length - 1;
        Complex dz = calcBn.multiply(dc);
        Complex z = referenceOrbit[iteration];
        
        while (iteration < maxIteration) {
    

            dz = referenceOrbit[refIteration].multiply(2).add(dz).multiply(dz).add(dc);  
            refIteration++;
            z = referenceOrbit[refIteration].add(dz);
            
            
            if (z.radius2() > 4) {
                break;
            }

            iteration++;
                
            if (refIteration == maxRefIteration || z.radius2() < dz.radius2()) {
                refIteration = 0;
                dz = z;
            }
        }
        if (iteration == maxIteration) {
            return maxIteration;

        }

        return iteration + 1 - (z.radius() - 2) / 4;

    }

    public Complex[] getReferenceOrbit() {
        return referenceOrbit;
    }
}

I checked other documents and organized them in my notes to derive the best expressions and codes for approximation, but they are still slow.

Even with 100,000 iterations, i want a way to render in a short period of time if the shape is simple.

I'm very curious if it's an optimization problem for code or something else. here is my approximation code.

(I found the problem that there was a glitch when the coordinates were very close to the pattern, but i decided not to consider this)

7
  • 1
    Have you profiled which part of your code takes how much time to find a possible bottleneck? Commented Sep 9, 2024 at 8:19
  • 1
    You may have a look at Wikipedia's page: en.wikipedia.org/wiki/… Commented Sep 9, 2024 at 9:37
  • 1
    You're using a pertubation theory method, but isn't that usually used to compute the reference path in high precision and then do iterations over a set of points with lower precision? It may be that you're just doing something over-complicated (which you won't see if you profile!) Also, you don't show the code which calls this class and how it's assigning points to the reference paths? Perhaps it's wrong? Commented Sep 10, 2024 at 7:12
  • 2
    I'm skeptical of the reference path code as well... aren't your complex numbers boxed, thus causing a ton of allocation and pointer dereferences when the points are used? If you wrote the code in a naive way, just iterating from the start point with no reference path and no allocations at all, I suspect your code will be a lot faster. You should also check that your use of the "Complex" class doesn't cause allocations and that the java compiler can compile it down to register operations. If it can't, just write double xReal = 1.0, xImag = 2.0; and so on, and code complex ops yourself. Commented Sep 10, 2024 at 7:21
  • 1
    FWIW I tried an approximation using the Julia Set algorithm, which is the same except that each iteration uses the current value for Julia, not the original value as MSet. Locally, the images are similar at deeper zoom levels. The advantage is gained that once the iteration orbit lands on a pixel you've already done you can pick up on the total (approximate) iteration without iterating further. You need to store the orbits. It's not very accurate because it clamps nearby values to that pixel. But if you want a dynamic zoom, detail is best avoided anyway. Commented Sep 22, 2024 at 18:15

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.