2009-07-10 55 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),并在递增迭代次数之前退出,因此不区分这种情况。