@@ -46,88 +46,88 @@ impl SeriesApproximation {
4646 }
4747 }
4848
49- pub fn step ( & mut self ) -> bool {
50- self . z . square_mut ( ) ;
51- self . z += & self . c ;
52-
53- let z_fixed = to_fixed ( & self . z ) ;
54-
55- if z_fixed. re . abs ( ) < 1e-300 && z_fixed. im . abs ( ) < 1e-300 {
56- println ! ( "found slow at: {}" , self . current_iteration) ;
57- }
49+ pub fn run ( & mut self ) {
50+ self . add_probe ( ComplexExtended :: new2 ( self . delta_top_left . mantissa . re , self . delta_top_left . mantissa . im , self . delta_top_left . exponent ) ) ;
51+ self . add_probe ( ComplexExtended :: new2 ( self . delta_top_left . mantissa . re , -self . delta_top_left . mantissa . im , self . delta_top_left . exponent ) ) ;
52+ self . add_probe ( ComplexExtended :: new2 ( -self . delta_top_left . mantissa . re , self . delta_top_left . mantissa . im , self . delta_top_left . exponent ) ) ;
53+ self . add_probe ( ComplexExtended :: new2 ( -self . delta_top_left . mantissa . re , -self . delta_top_left . mantissa . im , self . delta_top_left . exponent ) ) ;
5854
59- self . next_coefficients [ 0 ] = to_extended ( & self . z ) ;
60- self . next_coefficients [ 1 ] = self . coefficients [ 0 ] * self . coefficients [ 1 ] * 2.0 + ComplexExtended :: new2 ( 1.0 , 0.0 , 0 ) ;
55+ let add_value = ComplexExtended :: new2 ( 1.0 , 0.0 , 0 ) ;
6156
62- // Calculate the new coefficents
63- for k in 2 ..=self . order {
64- let mut sum = self . coefficients [ 0 ] * self . coefficients [ k] ;
57+ // Can be changed later into a better loop - this function could also return some more information
58+ while self . current_iteration < self . maximum_iteration {
59+ self . z . square_mut ( ) ;
60+ self . z += & self . c ;
6561
66- for j in 1 ..=( ( k - 1 ) / 2 ) {
67- sum += self . coefficients [ j] * self . coefficients [ k - j] ;
68- }
69- sum *= 2.0 ;
62+ let z_fixed = to_fixed ( & self . z ) ;
7063
71- // If even, we include the mid term as well
72- if k % 2 == 0 {
73- sum += self . coefficients [ k / 2 ] * self . coefficients [ k / 2 ] ;
64+ if z_fixed. re . abs ( ) < 1e-300 && z_fixed. im . abs ( ) < 1e-300 {
65+ println ! ( "found slow at: {}" , self . current_iteration) ;
7466 }
7567
76- sum. reduce ( ) ;
77- self . next_coefficients [ k] = sum;
78- }
79-
80- // this section takes about half of the time
81- for i in 0 ..self . original_probes . len ( ) {
82- // step the probe points using perturbation
83- self . current_probes [ i] = self . current_probes [ i] * ( self . coefficients [ 0 ] * 2.0 + self . current_probes [ i] ) ;
84- self . current_probes [ i] += self . original_probes [ i] ;
85-
86- // TODO this probably does not need to be done every iteration
87- self . current_probes [ i] . reduce ( ) ;
88-
89- // get the new approximations
90- let mut series_probe = self . next_coefficients [ 1 ] * self . approximation_probes [ i] [ 0 ] ;
91- let mut derivative_probe = self . next_coefficients [ 1 ] * self . approximation_probes_derivative [ i] [ 0 ] ;
68+ self . next_coefficients [ 0 ] = to_extended ( & self . z ) ;
69+ self . next_coefficients [ 1 ] = self . coefficients [ 0 ] * self . coefficients [ 1 ] * 2.0 + add_value;
70+ self . next_coefficients [ 0 ] . reduce ( ) ;
71+ self . next_coefficients [ 1 ] . reduce ( ) ;
9272
73+ // Calculate the new coefficents
9374 for k in 2 ..=self . order {
94- series_probe += self . next_coefficients [ k] * self . approximation_probes [ i] [ k - 1 ] ;
95- derivative_probe += self . next_coefficients [ k] * self . approximation_probes_derivative [ i] [ k - 1 ] ;
96- } ;
75+ let mut sum = self . coefficients [ 0 ] * self . coefficients [ k] ;
9776
98- let relative_error = ( self . current_probes [ i] - series_probe) . norm_square ( ) ;
99- let mut derivative = derivative_probe. norm_square ( ) ;
77+ for j in 1 ..=( ( k - 1 ) / 2 ) {
78+ sum += self . coefficients [ j] * self . coefficients [ k - j] ;
79+ }
80+ sum *= 2.0 ;
10081
101- // Check to make sure that the derivative is greater than or equal to 1
102- if derivative . to_float ( ) < 1. 0 {
103- derivative = FloatExtended :: new ( 1.0 , 0 ) ;
104- }
82+ // If even, we include the mid term as well
83+ if k % 2 == 0 {
84+ sum += self . coefficients [ k / 2 ] * self . coefficients [ k / 2 ] ;
85+ }
10586
106- // Check that the error over the derivative is less than the pixel spacing
107- if relative_error / derivative > self . delta_pixel_square {
108- self . z -= & self . c ;
109- self . z . sqrt_mut ( ) ;
110- return false ;
87+ sum. reduce ( ) ;
88+ self . next_coefficients [ k] = sum;
11189 }
112- }
11390
114- // If the approximation is valid, continue
115- self . current_iteration += 1 ;
116-
117- // Swap the two coefficients buffers
118- swap ( & mut self . coefficients , & mut self . next_coefficients ) ;
119- self . current_iteration < self . maximum_iteration
120- }
91+ // this section takes about half of the time
92+ for i in 0 ..self . original_probes . len ( ) {
93+ // step the probe points using perturbation
94+ self . current_probes [ i] = self . current_probes [ i] * ( self . coefficients [ 0 ] * 2.0 + self . current_probes [ i] ) ;
95+ self . current_probes [ i] += self . original_probes [ i] ;
96+
97+ // TODO this probably does not need to be done every iteration
98+ self . current_probes [ i] . reduce ( ) ;
99+
100+ // get the new approximations
101+ let mut series_probe = self . next_coefficients [ 1 ] * self . approximation_probes [ i] [ 0 ] ;
102+ let mut derivative_probe = self . next_coefficients [ 1 ] * self . approximation_probes_derivative [ i] [ 0 ] ;
103+
104+ for k in 2 ..=self . order {
105+ series_probe += self . next_coefficients [ k] * self . approximation_probes [ i] [ k - 1 ] ;
106+ derivative_probe += self . next_coefficients [ k] * self . approximation_probes_derivative [ i] [ k - 1 ] ;
107+ } ;
108+
109+ let relative_error = ( self . current_probes [ i] - series_probe) . norm_square ( ) ;
110+ let mut derivative = derivative_probe. norm_square ( ) ;
111+
112+ // Check to make sure that the derivative is greater than or equal to 1
113+ if derivative. to_float ( ) < 1.0 {
114+ derivative. mantissa = 1.0 ;
115+ derivative. exponent = 0 ;
116+ }
117+
118+ // Check that the error over the derivative is less than the pixel spacing
119+ if relative_error / derivative > self . delta_pixel_square {
120+ self . z -= & self . c ;
121+ self . z . sqrt_mut ( ) ;
122+ return ;
123+ }
124+ }
121125
122- pub fn run ( & mut self ) {
123- self . add_probe ( ComplexExtended :: new2 ( self . delta_top_left . mantissa . re , self . delta_top_left . mantissa . im , self . delta_top_left . exponent ) ) ;
124- self . add_probe ( ComplexExtended :: new2 ( self . delta_top_left . mantissa . re , -self . delta_top_left . mantissa . im , self . delta_top_left . exponent ) ) ;
125- self . add_probe ( ComplexExtended :: new2 ( -self . delta_top_left . mantissa . re , self . delta_top_left . mantissa . im , self . delta_top_left . exponent ) ) ;
126- self . add_probe ( ComplexExtended :: new2 ( -self . delta_top_left . mantissa . re , -self . delta_top_left . mantissa . im , self . delta_top_left . exponent ) ) ;
126+ // If the approximation is valid, continue
127+ self . current_iteration += 1 ;
127128
128- // Can be changed later into a better loop - this function could also return some more information
129- while self . step ( ) {
130- continue ;
129+ // Swap the two coefficients buffers
130+ swap ( & mut self . coefficients , & mut self . next_coefficients ) ;
131131 }
132132 }
133133
@@ -136,23 +136,23 @@ impl SeriesApproximation {
136136 self . original_probes . push ( delta_probe) ;
137137 self . current_probes . push ( delta_probe) ;
138138
139- let mut delta_probe_n = delta_probe;
139+ let mut current_value = delta_probe;
140140
141- let mut delta_probe_n_2 = Vec :: with_capacity ( self . order + 1 ) ;
142- let mut delta_probe_n_derivative_2 = Vec :: with_capacity ( self . order + 1 ) ;
141+ let mut delta_n = Vec :: with_capacity ( self . order + 1 ) ;
142+ let mut delta_derivative_n = Vec :: with_capacity ( self . order + 1 ) ;
143143
144144 // The first element will be 1, in order for the derivative to be calculated
145- delta_probe_n_2 . push ( delta_probe_n ) ;
146- delta_probe_n_derivative_2 . push ( ComplexExtended :: new2 ( 1.0 , 0.0 , 0 ) ) ;
145+ delta_n . push ( current_value ) ;
146+ delta_derivative_n . push ( ComplexExtended :: new2 ( 1.0 , 0.0 , 0 ) ) ;
147147
148148 for i in 1 ..=self . order {
149- delta_probe_n_derivative_2 . push ( delta_probe_n * ( i + 1 ) as f64 ) ;
150- delta_probe_n *= delta_probe;
151- delta_probe_n_2 . push ( delta_probe_n ) ;
149+ delta_derivative_n . push ( current_value * ( i + 1 ) as f64 ) ;
150+ current_value *= delta_probe;
151+ delta_n . push ( current_value ) ;
152152 }
153153
154- self . approximation_probes . push ( delta_probe_n_2 ) ;
155- self . approximation_probes_derivative . push ( delta_probe_n_derivative_2 ) ;
154+ self . approximation_probes . push ( delta_n ) ;
155+ self . approximation_probes_derivative . push ( delta_derivative_n ) ;
156156 }
157157
158158 // Get the current reference, and the current number of iterations done
0 commit comments