Clojure / Java Мандельброт Фрактальный рисунок - PullRequest
3 голосов
/ 11 июля 2009

Я пытаюсь перенести этот алгоритм для закрытия.

Мой код

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

Функции умножения, сложения и абс работают как надо. Я проверил их с помощью калькулятора. Однако для следующих значений:

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

Может кто-нибудь заметить мою ошибку?

1 Ответ

8 голосов
/ 11 июля 2009

Я заметил две различия .

  1. Реализация Java начинается с z = (x, y), а не с вашей, которая начинается с (0, 0). Поскольку ваша рекурсивная формула имеет вид z = z ^ 2 + c, (0, 0) ^ 2 + (x, y) = (x, y), поэтому начинать с (x, y) так же, как и делать первую итерацию. Поэтому количество итераций будет на одну меньше, чем у вас, из-за этого.
  2. Реализация Java увеличивает число итераций после , проверяя, находится ли результат, z, в пределах 2 единиц от начала координат, и не увеличивает его в ином случае, тогда как ваш увеличивает итерации каждый раз. Из-за этого количество итераций будет на одну меньше, чем у вас.

Так что, вероятно, это объясняет различия в ваших результатах.

Я бы сказал, что ваша реализация более правильная, потому что она различает случаи, когда | z | > 2 после одной итерации (то есть где | (x, y) |> 2) и где | z | > 2 после двух итераций (т. Е. Где | (x ^ 2-y ^ 2 + x, 2xy + y) |> 2), тогда как реализация Java выполнит свою первую итерацию, давая (x ^ 2-y ^ 2 + x , 2xy + y) и выйдите перед увеличением числа итераций, таким образом, не делая различий между этими случаями.

...