|
10 | 10 |
|
11 | 11 | from operator import add, mul |
12 | 12 | from itertools import repeat |
13 | | -from math import sin, pi, log2 |
| 13 | +from math import sin, cos, pi, log2 |
| 14 | +from cmath import sin as complex_sin |
14 | 15 |
|
15 | 16 | from ..fun import curry |
16 | 17 | from ..funutil import Values |
@@ -219,18 +220,19 @@ def best_differentiate_with_tol(h0, f, x, eps): |
219 | 220 | # J. N. Lyness. 1967. Numerical algorithms based on the theory of complex variables, |
220 | 221 | # Proc. ACM 22nd Nat. Conf., Thompson Book Co., Washington, DC, pp. 124–134. |
221 | 222 | # |
| 223 | + # See also |
| 224 | + # Joaquim J Martins, Peter Sturdza, Juan J Alonso. The complex-step derivative approximation. |
| 225 | + # ACM Transactions on Mathematical Software, Association for Computing Machinery, 2003, 29, |
| 226 | + # pp.245-262. 10.1145/838250.838251. hal-01483287. |
| 227 | + # https://hal.archives-ouvertes.fr/hal-01483287/document |
| 228 | + # |
222 | 229 | # So this technique has been known since the late 1960s, but even as of this writing, |
223 | 230 | # 55 years later (2022), it has not seen much use. |
224 | | - try: |
225 | | - # We need a `sin` that can handle complex numbers, so stdlib's won't cut the mustard. |
226 | | - import numpy as np |
227 | | - eps = 1e-150 |
228 | | - def complex_diff(f, x): |
229 | | - return np.imag((f(x + eps * 1j) / eps)) |
230 | | - # This is so accurate in this simple case that we can test for floating point equality. |
231 | | - test[complex_diff(np.sin, 0.1) == np.cos(0.1)] |
232 | | - except ImportError: |
233 | | - warn["Could not import NumPy; alternative numerical differentiation test skipped."] |
| 231 | + eps = 1e-150 |
| 232 | + def complex_diff(f, x): |
| 233 | + return (f(x + eps * 1j) / eps).imag |
| 234 | + # This is so accurate in this simple case that we can test for floating point equality. |
| 235 | + test[complex_diff(complex_sin, 0.1) == cos(0.1)] |
234 | 236 |
|
235 | 237 | # pi approximation with Euler series acceleration |
236 | 238 | # |
|
0 commit comments