Skip to content

Commit 05ccbab

Browse files
authored
Merge pull request #8 from jackyarndley/extended
Extended
2 parents 3eb6313 + a850d11 commit 05ccbab

18 files changed

+897
-224
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
/target
22
**/*.rs.bk
3-
.idea
3+
.idea
4+
*.kfr

Cargo.lock

Lines changed: 18 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ pbr = "1.0.2"
1212
rayon = "1.3.0"
1313
packed_simd = "0.3.3"
1414
rug = "1.7.0"
15+
float-extended = {path = "../rust-float-extended/"}
16+
itertools = "0.9.0"
1517

1618
#Additional commands that can improve performance (maybe by around 5-10%)
1719
#[profile.release]

output.png

1.25 MB
Loading

src/bin/main.rs

Lines changed: 43 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,74 +1,67 @@
11
use std::time::Instant;
22
use rust_fractal::renderer::FractalRenderer;
3+
use std::fs;
4+
use std::io::{stdout, stdin, Write};
35

46
fn main() {
57
println!("Mandelbrot Renderer");
6-
// let center = (
7-
// "-1.99996619445037030418434688506350579675531241540724851511761922944801584242342684381376129778868913812287046406560949864353810575744772166485672496092803920095332",
8-
// "+0.00000000000000000000000000000000030013824367909383240724973039775924987346831190773335270174257280120474975614823581185647299288414075519224186504978181625478529");
9-
// let zoom = 2.3620330788506154104770818136626E157;
108

11-
// let center = (
12-
// "0.0",
13-
// "0.0");
14-
// let zoom = 1.0;
9+
// TODO on some images, we may need to check the imaginary part of the floatexp to make sure that is not too large.
1510

16-
// let center = (
17-
// "-0.749999987350877481864108888020013802837969258626230419972587823828734338471228477079750588709551510361714463695461745528645748607681279674273355384334270208362211787387351792878073779449767292692440",
18-
// "0.001000038688236832013124581230049849132759425863378894883003211011278068229551274712347955044740933397589760194545872789087012331273586364914484522575986336846199522726507205442204060303594956029930");
19-
// let zoom = 3.7E191;
11+
let mut s = String::new();
12+
print!("File to render: ");
13+
let _ = stdout().flush();
14+
stdin().read_line(&mut s).expect("User did not enter a correct string.");
2015

21-
// let center = (
22-
// "-1.689573325432279612075987864633746594591438093139394112928000260",
23-
// "0.000000000000000000000000000000000145514706909258179374258");
24-
// let zoom = 1.2980742146337048E34;
16+
s.pop();
2517

26-
// let center = (
27-
// "-1.999999999138270118722935763129859470012913240693218269085000",
28-
// "-0.000000000000000000322680215517275822769282166130504217892606");
29-
// let zoom = 1.63e030;
18+
if !s.ends_with(".kfr") {
19+
s.push_str(".kfr")
20+
};
3021

31-
// let center = (
32-
// "-1.76904090125288168240284276810365472222460651367280300612031519864776551390840630119504817227707689276670981344397551593371805167279428144061791279408701383958080000000000000000000000002e+00",
33-
// "-3.1605400272558568759745268636087334444350515177571908056976983793515506960262149704114708190147368048572976192049103272074188848768835600195188510326583157513e-03");
34-
// let zoom = 7.5E139;
22+
println!("Reading: {}", s);
3523

36-
// let center = (
37-
// "-1.7685304554715107439359975226423287998937254896566074423088827415719065562223946222490318219590860313620613389226996388",
38-
// "0.0059445386042946892550190097831583153039526746987365071641624831873576346016435037438597231970921541448697901394734283301");
39-
// let zoom = 2.00000000000E113;
24+
let data = fs::read_to_string(s).expect("Unable to read file.");
4025

41-
// let center = (
42-
// "-0.74977496303986055825690204249855929432518723234763348374372443797716597482713646451452176727030299366505937952743219986590574037612687173829307656886118099999999999999999999999",
43-
// "-0.06638008421017090687747407166586874456952046519386815946449195256714882710925246541317934635067121915196760463342031197755105049354085337445454326026704199999999999999999999999");
44-
// let zoom = 4.70017300819E149;
26+
let mut center_re = "-0.75";
27+
let mut center_im = "0.0";
28+
let mut zoom = "1E0";
29+
let mut iterations = "1000";
4530

46-
// let center = (
47-
// "-1.99996619445037030418434688506350579675531241540724851511761922944801584242342684381376129778868913812287046406560949864353810575744772166485672496092803920095332176654846785710146671838403830455177782981641506704068474778442",
48-
// "-0.000000000000000000000000000000000300138243679093832407249730397759249873468311907733352701742572801204749756148235811856472992884140755192241865049781816254785289455481579902975133989545509287024987599289178526901586954397865");
49-
// let zoom = 8.80307862787E167;
31+
for line in data.lines() {
32+
let mut parts = line.split_whitespace();
33+
// println!("{}", line);
34+
let temp = parts.next().unwrap();
5035

51-
let center = (
52-
"-1.479796270901760024425279934770411525645551054432599517909807632824286254403907594526888466099962805022975196472549771681831234491695559852583955204986197762293872769474806903995564259040667568599770094383157857518790853771783314763231302599999999999999999999999998",
53-
"-0.001199443952813447746281973233374468444560314114132538362037569205657422216739564521471119107626453330996365067987088146663639996715939831819152248618042255824652268918299630897525386638029428706473919823922522752497780934312003352081931299999999999999999999999998");
54-
let zoom = 3.27799999998E235;
55-
56-
// let center = (
57-
// "-0.74962449737876168207862620426836138684529527812364025754481571424558286479672801698750203976779135608148687747196595174858125388297577788573082753210469806739721377901297451172624762450940529814713048377873612297220313016947039287469999999999999999",
58-
// "0.03427010874046016945172951545749474868051534672439111853174854738370595772935930171842999778713222794215453436628998200591914208207632674780780978496784843807690510401829301309069542198413574392425885166367231192087416338497065495509999999999999999");
59-
// let zoom = 7.58065474756E227;
36+
match temp {
37+
"Re:" => {
38+
center_re = parts.next().unwrap();
39+
},
40+
"Im:" => {
41+
center_im = parts.next().unwrap();
42+
}
43+
"Zoom:" => {
44+
zoom = parts.next().unwrap();
45+
},
46+
"Iterations:" => {
47+
iterations = parts.next().unwrap();
48+
}
49+
_ => {}
50+
}
51+
}
6052

53+
println!("Zoom: {}", zoom);
6154

6255
let mut renderer = FractalRenderer::new(
6356
1000,
6457
1000,
6558
zoom,
66-
100000,
67-
center.0,
68-
center.1,
59+
iterations.parse::<usize>().unwrap(),
60+
center_re,
61+
center_im,
6962
0.001,
70-
false,
71-
64
63+
true,
64+
16
7265
);
7366

7467
let time = Instant::now();

src/lib.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
// pub mod renderer;
1+
#![feature(extra_log_consts)]
22
pub mod renderer;
33
pub mod util;
4-
pub mod colouring;
54
pub mod math;

src/math/mod.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
// pub mod perturbation_f64;
2-
// pub mod perturbation_f64_vectorised;
3-
pub mod perturbation;
4-
pub mod reference;
5-
pub mod series_approximation;
1+
pub mod perturbation_double;
2+
pub mod perturbation_extended;
3+
pub mod reference_double;
4+
pub mod reference_extended;
5+
pub mod series_approximation_double;
6+
pub mod series_approximation_extended;

src/math/perturbation.rs renamed to src/math/perturbation_double.rs

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,16 @@
1-
use crate::math::reference::Reference;
2-
use crate::util::PixelData;
3-
1+
use crate::math::reference_double::ReferenceDouble;
2+
use crate::util::PixelDataDouble;
43
use rayon::prelude::*;
54

6-
pub struct Perturbation {}
5+
pub struct PerturbationDouble {}
76

8-
impl Perturbation {
9-
pub fn iterate(pixel_data: &mut Vec<PixelData>, reference: &Reference, maximum_iteration: usize) {
10-
pixel_data.par_chunks_mut(1)
7+
impl PerturbationDouble {
8+
pub fn iterate(pixel_data: &mut Vec<PixelDataDouble>, reference: &ReferenceDouble, reference_current_iteration: usize) {
9+
pixel_data.par_chunks_mut(4)
1110
.for_each(|pixel_data| {
1211
for packet in pixel_data {
13-
// TODO investigate setting up a floatexp-type thing which only rescales every 500 or so iterations
14-
1512
// normal
16-
while packet.iteration < maximum_iteration {
13+
while packet.iteration < reference_current_iteration {
1714
// This uses the difference between the starting iteration of the reference - can be used to skip some
1815
let z = packet.delta_current + reference.z_reference[packet.iteration - reference.start_iteration];
1916
let z_norm = z.norm_sqr();
@@ -24,13 +21,13 @@ impl Perturbation {
2421
break;
2522
}
2623

27-
if z_norm > 65536.0 {
24+
if z_norm > 1e16 {
2825
packet.escaped = true;
2926
packet.delta_current = z;
3027
break;
3128
}
3229

33-
packet.derivative_current = 2.0 * z * packet.derivative_current + 1.0;
30+
// packet.derivative_current = 2.0 * z * packet.derivative_current + 1.0;
3431
packet.delta_current = 2.0 * reference.z_reference[packet.iteration - reference.start_iteration] * packet.delta_current + packet.delta_current * packet.delta_current + packet.delta_reference;
3532
packet.iteration += 1;
3633
}

src/math/perturbation_extended.rs

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
use crate::util::PixelDataExtended;
2+
use float_extended::util::FloatExp;
3+
4+
use rayon::prelude::*;
5+
use crate::math::reference_extended::ReferenceExtended;
6+
use std::cmp::max;
7+
8+
pub struct PerturbationExtended {}
9+
10+
impl PerturbationExtended {
11+
pub fn iterate(pixel_data: &mut Vec<PixelDataExtended>, reference: &ReferenceExtended, reference_current_iteration: usize) {
12+
pixel_data.par_chunks_mut(4)
13+
.for_each(|pixel_data| {
14+
for packet in pixel_data {
15+
let original_reference = (packet.delta_reference, packet.p_initial);
16+
17+
// normalise so that the current d0 is same as current dn
18+
packet.delta_reference *= 1.0.ldexp(packet.p_initial - packet.p_current);
19+
packet.p_initial = packet.p_current;
20+
let mut temp = 1.0.ldexp(packet.p_current);
21+
22+
// normal but with added exponent
23+
while packet.iteration < reference_current_iteration {
24+
// packet.derivative_current = 2.0 * z * packet.derivative_current + 1.0;
25+
let z_reference = reference.z_reference[packet.iteration - reference.start_iteration];
26+
27+
if packet.p_current > -500 {
28+
let mut z = 0.5 * z_reference.0;
29+
30+
if z_reference.1 < 0 {
31+
z *= 1.0.ldexp(z_reference.1);
32+
}
33+
34+
z += packet.delta_current * temp;
35+
let z_norm = z.norm_sqr();
36+
37+
if z_norm < reference.z_tolerance[packet.iteration - reference.start_iteration] {
38+
packet.glitched = true;
39+
packet.delta_current = z;
40+
break;
41+
}
42+
43+
if z_norm > 1e16 {
44+
packet.escaped = true;
45+
packet.delta_current = z;
46+
break;
47+
}
48+
49+
// We have already done this check, we only need to check if the current value is in floatexp form
50+
if z_reference.1 < 0 {
51+
// we rescale back to the initial delta level
52+
53+
// this is the new p value we will be using
54+
let new_p = max(packet.p_current + z_reference.1, original_reference.1);
55+
56+
packet.delta_reference = original_reference.0 * 1.0.ldexp(original_reference.1 - new_p);
57+
58+
let temp9 = z_reference.0 * 1.0.ldexp(packet.p_current + z_reference.1 - new_p) + packet.delta_current * 1.0.ldexp(2 * packet.p_current - new_p);
59+
60+
packet.delta_current *= temp9;
61+
packet.delta_current += packet.delta_reference;
62+
packet.p_current = new_p;
63+
temp = 1.0.ldexp(packet.p_current);
64+
} else {
65+
// for the delta squared bit, as we want it in terms of the current p level, the powers are 2^(2 * pinit) / 2^(pinit)
66+
let temp2 = packet.delta_current * temp + z_reference.0;
67+
packet.delta_current *= temp2;
68+
packet.delta_current += packet.delta_reference;
69+
}
70+
} else {
71+
// We have already done this check, we only need to check if the current value is in floatexp form
72+
if z_reference.1 < 0 {
73+
// we rescale back to the initial delta level
74+
75+
// this is the new p value we will be using
76+
let new_p = max(packet.p_current + z_reference.1, original_reference.1);
77+
78+
packet.delta_reference = original_reference.0 * 1.0.ldexp(original_reference.1 - new_p);
79+
80+
let temp9 = z_reference.0 * 1.0.ldexp(packet.p_current + z_reference.1 - new_p) + packet.delta_current * 1.0.ldexp(2 * packet.p_current - new_p);
81+
82+
packet.delta_current *= temp9;
83+
packet.delta_current += packet.delta_reference;
84+
packet.p_current = new_p;
85+
temp = 1.0.ldexp(packet.p_current);
86+
} else {
87+
packet.delta_current *= z_reference.0;
88+
packet.delta_current += packet.delta_reference;
89+
}
90+
}
91+
92+
packet.iteration += 1;
93+
94+
// 2x time with 100 vs 1
95+
if packet.iteration % 400 == 0 {
96+
// here we should do the rescale, based on the real value
97+
let (temp_mantissa, added_exponent) = packet.delta_current.re.frexp();
98+
packet.delta_current.re = temp_mantissa;
99+
100+
packet.delta_current.im = packet.delta_current.im.ldexp(-added_exponent);
101+
packet.p_current += added_exponent;
102+
packet.delta_reference.re = packet.delta_reference.re.ldexp(-added_exponent);
103+
packet.delta_reference.im = packet.delta_reference.im.ldexp(-added_exponent);
104+
temp = 1.0.ldexp(packet.p_current);
105+
// packet.derivative_current /= 1.0.ldexp(added_exponent);
106+
}
107+
}
108+
}
109+
});
110+
}
111+
}
112+
113+
114+

0 commit comments

Comments
 (0)