2016-10-26 3 views
0

Следующая функция вычисляет количество орбит, необходимое для mandelbrot fractal первоначального значения, чтобы «убежать»:Как удалить изменяемую переменную в этой функции mandelbrot без рекурсии?

extern crate num; 

fn mandel_escape(x: f32, y: f32, limit: f32, orbits: u32) -> Option<u32> { 
    let c = num::complex::Complex32::new(x, y); 
    let mut z = c; 
    for i in 0 .. orbits { 
     z = z * z + c; 
     if z.norm_sqr() > limit { return Some(i); } 
    } 
    None 
} 

Я понимаю, что нет никакой гарантий оптимизации хвостового вызова в Русте. Как я могу удалить изменяемую переменную в этой функции без рекурсии?

+1

Почему? Вы можете злоупотреблять некоторыми итераторными адаптерами ('fold' и' take_while', просто игнорируя значение цикла), но это просто скроет вам изменчивость. Это совершенно идиоматическая Руста. Является ли это проблемой игрушек, и у вас есть какая-то конкретная проблема, когда что-то подобное делает жалованье? – LinearZoetrope

+0

Также, пытаясь быть полезным, не значит. Комментарии усиливают терпение. – LinearZoetrope

+0

Хотел бы свести к минимуму изменчивость, поскольку он помогает понять логику. Ссылочная целостность и все такое. – rityzmon

ответ

2

Невозможно.

Для каждой итерации в какой-то момент вам нужно создать значения z. Таким образом, либо у вас есть изменяемое место для хранения каждого, либо вам нужно место для всех из них.

Вы можете скрыть переменчивость внутри итератора, хотя:

struct MandelIterator { 
    c: f32, 
    z: f32, 
} 

fn mandel_iter(c: f32) -> MandelIterator { 
    MandelIterator { c: c, z: 0.0 } 
} 

impl Iterator for MandelIterator { 
    type Item = f32; 
    fn next(&mut self) -> Option<Self::Item> { 
     self.z = self.z * self.z + self.c; 
     Some(self.z) 
    } 
} 

fn mandel_escape(x: f32, y: f32, limit: f32, orbits: usize) -> Option<usize> { 
    for (i, z) in mandel_iter(x*y).enumerate().take(orbits) { 
     if z.abs() > limit { return Some(i); } 
    } 
    None 
} 

fn main() { 
    println!("{:?}", mandel_escape(1.00001, 1.00001, 40999.0, 4)); 
} 
+0

Не совсем, я не думаю. Вы можете написать один, но простой скучный для цикла, вероятно, легче понять. :-) –

Смежные вопросы