2009-07-10 14 views
3

私はこのalgorithmをクロージャに移植しようとしています。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

の違いがの2つあります。

  1. Javaの実装は、(0、0)から始まるものではなく、z =(x、y)から開始します。あなたの再帰式は(0、0)^ 2 +(x、y)=(x、y)であるので、(x、y)で始まるので最初の反復と同じです。このため、反復の数はあなたのものより1つ少なくなります。
  2. の後にの結果がzから2単位以内にあるかどうかをチェックし、それ以外の場合はインクリメントしませんが、毎回反復回数が増えます。繰り返しの回数もこれよりも少なくなるでしょう。

これはおそらく結果の違いを説明します。

私は実装がより正確であると主張したいと思います。これは、| z | (すなわち、|(x、y)|> 2)であり、| z | (x^2-y^2 + x、2xy + y)|> 2)、Javaの実装では最初の反復を実行し、(x^2-y^2 + x 、2xy + y)を計算し、反復回数をインクリメントする前に終了する。したがって、この場合を区別しない。