@@ -46,88 +46,88 @@ impl SeriesApproximation {
46
46
}
47
47
}
48
48
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 ) ) ;
58
54
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 ) ;
61
56
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 ;
65
61
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 ) ;
70
63
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) ;
74
66
}
75
67
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 ( ) ;
92
72
73
+ // Calculate the new coefficents
93
74
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] ;
97
76
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 ;
100
81
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
+ }
105
86
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;
111
89
}
112
- }
113
90
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
+ }
121
125
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 ;
127
128
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 ) ;
131
131
}
132
132
}
133
133
@@ -136,23 +136,23 @@ impl SeriesApproximation {
136
136
self . original_probes . push ( delta_probe) ;
137
137
self . current_probes . push ( delta_probe) ;
138
138
139
- let mut delta_probe_n = delta_probe;
139
+ let mut current_value = delta_probe;
140
140
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 ) ;
143
143
144
144
// 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 ) ) ;
147
147
148
148
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 ) ;
152
152
}
153
153
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 ) ;
156
156
}
157
157
158
158
// Get the current reference, and the current number of iterations done
0 commit comments