Clojure / Java Mandelbrot分形绘图

时间:2009-07-10 21:58:45

标签: java lisp clojure mandelbrot

我正在尝试将此algorithm移植到clojure。

我的代码是

(defn calc-iterations [x y] 
  (let [c (struct complex x y)]
    (loop [z (struct complex 0 0) 
           iterations 0]
      (if (and (< 2.0 (abs z))
               (> max-iterations iterations))
        iterations
        (recur (add c (multiply z z)) (inc iterations))))))

乘以,add和abs函数正常工作。我用计算器对它们进行了测试。但是对于以下值:

(calc-iterations 0.60703135 -0.33984375) ; should give me 2, instead I get 4
(calc-iterations -1.8421874 0.3515625 )  ; should give me 1, instead I get 3

我正在使用我在网上找到的另一个java applet检查正确的迭代次数。它似乎工作,因为它产生正确的输出。它的迭代函数是

protected int calcIterations( float x, float y ) {
    int iterations = 0;

    float xn = x, yn = y;

    while ( iterations < MAX_ITERATIONS ) {
        float xn1 = xn*xn - yn*yn;
        float yn1 = 2*xn*yn;

        xn = xn1 + x;
        yn = yn1 + y;

        float magsq = xn*xn + yn*yn;

        if ( magsq > 4 )
            break;

        iterations++;
    }

    System.out.println( x + " " + y + " " + iterations );
    return iterations;
}

有人可以发现我的错误吗?

1 个答案:

答案 0 :(得分:8)

我发现了两个差异

  1. Java实现从z =(x,y)开始,而不是从(0,0)开始的。由于您的递归公式为z = z ^ 2 + c,(0,0)^ 2 +(x,y)=(x,y),因此从(x,y)开始与进行第一次迭代相同。因此,迭代次数将比你的少一次。
  2. 在检查结果z是否在距离原点2个单位之内时,Java实现会增加迭代次数,否则不增加它,而每次增加迭代次数。由于这个原因,迭代次数将比你的少一次。
  3. 因此,这可能会导致结果的差异。

    我认为你的实现更正确,因为它区分了| z |的情况&GT;在一次迭代之后(即,其中|(x,y)|> 2),并且其中| z | &GT; 2次迭代后(即|(x ^ 2-y ^ 2 + x,2xy + y)|&gt; 2),而Java实现将执行其第一次迭代,给出(x ^ 2-y ^ 2 + x ,2xy + y),并在递增迭代次数之前退出,因此无法区分这种情况。