... | ... |
@@ -184,15 +184,41 @@ class Interval: |
184 | 184 |
|
185 | 185 |
return ivals |
186 | 186 |
|
187 |
+ def c_diff_split(self, ndiv_max=20): |
|
188 |
+ parent = self.parent |
|
189 |
+ c_old = self.T @ parent.c[parent.depth] |
|
190 |
+ c_diff = norm(self.c[0] - c_old) |
|
191 |
+ |
|
192 |
+ self.ndiv = (parent.ndiv |
|
193 |
+ + (abs(parent.c[0, 0]) > 0 |
|
194 |
+ and self.c[0, 0] / parent.c[0, 0] > 2)) |
|
195 |
+ |
|
196 |
+ if self.ndiv > ndiv_max and 2*self.ndiv > self.rdepth: |
|
197 |
+ raise DivergentIntegralError(self) |
|
198 |
+ |
|
199 |
+ return c_diff, False |
|
200 |
+ |
|
201 |
+ def c_diff_refine(self): |
|
202 |
+ c_diff = norm(self.c[self.depth - 1] - self.c[self.depth]) # c_old - c |
|
203 |
+ c_new = self.c[self.depth, :ns[self.depth]] |
|
204 |
+ force_split = c_diff > hint * norm(c_new) |
|
205 |
+ return c_diff, force_split |
|
206 |
+ |
|
187 | 207 |
def complete_process(self): |
188 | 208 |
"""Calculate the integral contribution and error from this interval, |
189 | 209 |
and update the done leaves of all ancestor intervals.""" |
190 |
- force_split = False |
|
210 |
+ fx = np.array([self.done_points[k] for k in sorted(self.done_points)]) |
|
211 |
+ self.c[self.depth, :ns[self.depth]] = _calc_coeffs(fx, self.depth) |
|
212 |
+ size = self.b - self.a |
|
213 |
+ self.igral = size * self.c[self.depth, 0] / sqrt(2) |
|
214 |
+ |
|
191 | 215 |
if self.parent is not None and self.rdepth > self.parent.rdepth: |
192 |
- self.process_split() |
|
216 |
+ c_diff, force_split = self.c_diff_split() |
|
193 | 217 |
else: |
194 |
- force_split = self.process_refine() |
|
218 |
+ c_diff, force_split = self.c_diff_refine() |
|
195 | 219 |
|
220 |
+ self.err = size * c_diff |
|
221 |
+ |
|
196 | 222 |
if self.done_leaves is not None and not len(self.done_leaves): |
197 | 223 |
# This interval contributes to the integral estimate. |
198 | 224 |
self.done_leaves = {self} |
... | ... |
@@ -229,39 +255,6 @@ class Interval: |
229 | 255 |
|
230 | 256 |
return force_split, remove |
231 | 257 |
|
232 |
- def process_split(self, ndiv_max=20): |
|
233 |
- fx = np.array([self.done_points[k] for k in sorted(self.done_points)]) |
|
234 |
- self.c[0, :ns[0]] = _calc_coeffs(fx, 0) |
|
235 |
- |
|
236 |
- parent = self.parent |
|
237 |
- c_old = self.T @ parent.c[parent.depth] |
|
238 |
- c_diff = norm(self.c[0] - c_old) |
|
239 |
- |
|
240 |
- ival_size = self.b - self.a |
|
241 |
- self.err = ival_size * c_diff |
|
242 |
- self.igral = ival_size * self.c[0, 0] / sqrt(2) |
|
243 |
- |
|
244 |
- self.ndiv = (parent.ndiv |
|
245 |
- + (abs(parent.c[0, 0]) > 0 |
|
246 |
- and self.c[0, 0] / parent.c[0, 0] > 2)) |
|
247 |
- |
|
248 |
- if self.ndiv > ndiv_max and 2*self.ndiv > self.rdepth: |
|
249 |
- raise DivergentIntegralError(self) |
|
250 |
- |
|
251 |
- def process_refine(self): |
|
252 |
- fx = np.array([self.done_points[k] for k in sorted(self.done_points)]) |
|
253 |
- self.c[self.depth, :ns[self.depth]] = c_new = _calc_coeffs(fx, self.depth) |
|
254 |
- |
|
255 |
- c_diff = norm(self.c[self.depth - 1] - self.c[self.depth]) |
|
256 |
- |
|
257 |
- ival_size = self.b - self.a |
|
258 |
- self.err = ival_size * c_diff |
|
259 |
- self.igral = ival_size * c_new[0] / sqrt(2) |
|
260 |
- |
|
261 |
- nc = norm(c_new) |
|
262 |
- force_split = nc > 0 and c_diff / nc > hint |
|
263 |
- return force_split |
|
264 |
- |
|
265 | 258 |
def __repr__(self): |
266 | 259 |
lst = [ |
267 | 260 |
'(a, b)=({:.5f}, {:.5f})'.format(self.a, self.b), |