2009-07-10 82 views
3

我試圖將此algorithm移植到clojure。Clojure/Java Mandelbrot分形繪圖

我的代碼是

(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)))))) 

乘,加和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小程序正確的迭代次數。它似乎正在工作,因爲它會產生正確的輸出。它的迭代功能是

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; 
} 

任何人都可以發現我的錯誤嗎?

回答

8

我發現了兩個差異

  1. Java實現從z =(x,y)開始,而不是從(0,0)開始的你的。由於你的遞歸公式是z = z^2 + c,(0,0)^ 2 +(x,y)=(x,y),因此從(x,y)開始與第一次迭代相同。因此,迭代的次數會比你的少一次。
  2. Java實現在之後檢查迭代次數檢查結果z是否在距離原點的2個單位內,否則不會遞增,而您的每次遞增迭代次數。迭代的次數會比你的少1次,因爲這也是。

因此,這可能會導致您的結果出現差異。

我認爲你的實現更加正確,因爲它區分了| z | > 2在一次迭代後(即|(x,y)|> 2),其中| z |在2次迭代之後(即,其中|(x^2-y^2 + x,2xy + y)|> 2),而Java實現將執行其第一次迭代,給出(x^2-y^2 + x ,2xy + y),並在遞增迭代次數之前退出,因此不區分這種情況。