numdifftools 0.9.42__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- numdifftools/2.session +3 -0
- numdifftools/__init__.py +69 -0
- numdifftools/_find_default_scale.py +210 -0
- numdifftools/core.py +635 -0
- numdifftools/example_functions.py +328 -0
- numdifftools/extrapolation.py +598 -0
- numdifftools/finite_difference.py +830 -0
- numdifftools/fornberg.py +676 -0
- numdifftools/info.py +253 -0
- numdifftools/license.py +33 -0
- numdifftools/limits.py +529 -0
- numdifftools/multicomplex.py +375 -0
- numdifftools/nd_algopy.py +613 -0
- numdifftools/nd_scipy.py +149 -0
- numdifftools/nd_statsmodels.py +368 -0
- numdifftools/numdifftools.prj +50 -0
- numdifftools/profile_numdifftools.py +74 -0
- numdifftools/profiletools.py +188 -0
- numdifftools/run_benchmark.py +210 -0
- numdifftools/step_generators.py +384 -0
- numdifftools/testing.py +68 -0
- numdifftools/tests/__init__.py +0 -0
- numdifftools/tests/hamiltonian.py +108 -0
- numdifftools/tests/test_example_functions.py +69 -0
- numdifftools/tests/test_extrapolation.py +162 -0
- numdifftools/tests/test_fornberg.py +162 -0
- numdifftools/tests/test_limits.py +117 -0
- numdifftools/tests/test_multicomplex.py +403 -0
- numdifftools/tests/test_nd_algopy.py +305 -0
- numdifftools/tests/test_nd_scipy.py +140 -0
- numdifftools/tests/test_nd_statsmodels.py +170 -0
- numdifftools/tests/test_numdifftools.py +601 -0
- numdifftools/tests/test_scripts.py +29 -0
- numdifftools/tests/test_step_generators.py +84 -0
- numdifftools/tests/test_wprofiletools.py +295 -0
- numdifftools-0.9.42.dist-info/METADATA +285 -0
- numdifftools-0.9.42.dist-info/RECORD +40 -0
- numdifftools-0.9.42.dist-info/WHEEL +4 -0
- numdifftools-0.9.42.dist-info/entry_points.txt +4 -0
- numdifftools-0.9.42.dist-info/licenses/LICENSE.txt +28 -0
numdifftools/2.session
ADDED
numdifftools/__init__.py
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
from __future__ import absolute_import
|
|
2
|
+
|
|
3
|
+
from . import extrapolation, limits, step_generators
|
|
4
|
+
from .core import (
|
|
5
|
+
Derivative,
|
|
6
|
+
Gradient,
|
|
7
|
+
Hessdiag,
|
|
8
|
+
Hessian,
|
|
9
|
+
Jacobian,
|
|
10
|
+
MaxStepGenerator,
|
|
11
|
+
MinStepGenerator,
|
|
12
|
+
Richardson,
|
|
13
|
+
dea3,
|
|
14
|
+
directionaldiff,
|
|
15
|
+
)
|
|
16
|
+
from .info import __doc__ as __doc__
|
|
17
|
+
|
|
18
|
+
__version__ = "0.9.42"
|
|
19
|
+
|
|
20
|
+
__all__ = (
|
|
21
|
+
"Derivative",
|
|
22
|
+
"Gradient",
|
|
23
|
+
"Hessian",
|
|
24
|
+
"Hessdiag",
|
|
25
|
+
"Jacobian",
|
|
26
|
+
"MaxStepGenerator",
|
|
27
|
+
"MinStepGenerator",
|
|
28
|
+
"Richardson",
|
|
29
|
+
"dea3",
|
|
30
|
+
"directionaldiff",
|
|
31
|
+
"extrapolation",
|
|
32
|
+
"limits",
|
|
33
|
+
"step_generators",
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def test(*options):
|
|
38
|
+
"""
|
|
39
|
+
Run tests for module using pytest.
|
|
40
|
+
|
|
41
|
+
Parameters
|
|
42
|
+
----------
|
|
43
|
+
*options : optional
|
|
44
|
+
options to pass to pytest. The most important ones include:
|
|
45
|
+
'-v', '--verbose':
|
|
46
|
+
increase verbosity.
|
|
47
|
+
'-q', '--quiet':
|
|
48
|
+
decrease verbosity.
|
|
49
|
+
'--doctest-modules':
|
|
50
|
+
run doctests in all .py modules
|
|
51
|
+
'--cov':
|
|
52
|
+
measure coverage for .py modules
|
|
53
|
+
'-h', '--help':
|
|
54
|
+
show full help message and display all possible options to use.
|
|
55
|
+
|
|
56
|
+
Returns
|
|
57
|
+
-------
|
|
58
|
+
exit_code: scalar
|
|
59
|
+
Exit code is 0 if all tests passed without failure.
|
|
60
|
+
|
|
61
|
+
Examples
|
|
62
|
+
--------
|
|
63
|
+
import numdifftols as nd
|
|
64
|
+
nd.test('-q', '--doctest-modules', '--cov', '--disable-warnings')
|
|
65
|
+
"""
|
|
66
|
+
|
|
67
|
+
import pytest
|
|
68
|
+
|
|
69
|
+
return pytest.main(["--pyargs", "numdifftools"] + list(options))
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
"""
|
|
2
|
+
This script can be run to find the empirical optimum scale for numdifftools.Derivative
|
|
3
|
+
given the method used.
|
|
4
|
+
|
|
5
|
+
Below are some results from previous runs compared with what is implemented in default_scale
|
|
6
|
+
function:
|
|
7
|
+
|
|
8
|
+
method="complex", order=2, x_values=[0.1, 0.5, 1.0, 5, 10, 50]:
|
|
9
|
+
n=1, mean scale=1.0330188679245282, median scale=1.0
|
|
10
|
+
n=2, mean scale=5.540094339622642, median scale=5.25
|
|
11
|
+
n=3, mean scale=8.36556603773585, median scale=7.625
|
|
12
|
+
n=4, mean scale=9.119791666666666, median scale=8.75
|
|
13
|
+
n=5, mean scale=10.154166666666667, median scale=9.625
|
|
14
|
+
n=6, mean scale=9.182291666666666, median scale=10.25
|
|
15
|
+
n=7, mean scale=14.078125, median scale=13.875
|
|
16
|
+
n=8, mean scale=14.307291666666666, median scale=14.875
|
|
17
|
+
n=9, mean scale=13.703125, median scale=13.625
|
|
18
|
+
n=10, mean scale=14.5625, median scale=14.75
|
|
19
|
+
|
|
20
|
+
Default scale with method="complex", order=2, x_values=[0.1, 0.5, 1.0, 5, 10, 50]:
|
|
21
|
+
n=1, scale=1.35
|
|
22
|
+
n=2, scale=5.0
|
|
23
|
+
n=3, scale=8.65
|
|
24
|
+
n=4, scale=11.35
|
|
25
|
+
n=5, scale=11.5
|
|
26
|
+
n=6, scale=11.7
|
|
27
|
+
n=7, scale=15.749999999999998
|
|
28
|
+
n=8, scale=21.35
|
|
29
|
+
n=9, scale=19.5
|
|
30
|
+
n=10, scale=20.78
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
method="central", order=2, x_values=0.5
|
|
34
|
+
n=1, scale=2.57894736842
|
|
35
|
+
n=2, scale=3.81578947368
|
|
36
|
+
n=3, scale=5.01315789474
|
|
37
|
+
n=4, scale=5.578125
|
|
38
|
+
n=5, scale=6.625
|
|
39
|
+
n=6, scale=7.59375
|
|
40
|
+
n=7, scale=8.65625
|
|
41
|
+
n=8, scale=9.28125
|
|
42
|
+
n=9, scale=9.84375
|
|
43
|
+
|
|
44
|
+
method="central", order=2, x_values=5
|
|
45
|
+
n=1, scale=2.86764705882
|
|
46
|
+
n=2, scale=5.41176470588
|
|
47
|
+
n=3, scale=6.23529411765
|
|
48
|
+
n=4, scale=5.859375
|
|
49
|
+
n=5, scale=8.025
|
|
50
|
+
n=6, scale=6.90625
|
|
51
|
+
n=7, scale=7.0625
|
|
52
|
+
n=8, scale=8.21875
|
|
53
|
+
n=9, scale=9.9375
|
|
54
|
+
|
|
55
|
+
method="central", order=2, x_values=[0.1, 0.5, 1.0, 5, 10, 50,]:
|
|
56
|
+
n=1, scale=2.77358490566
|
|
57
|
+
n=2, scale=4.75471698113
|
|
58
|
+
n=3, scale=5.19575471698
|
|
59
|
+
n=4, scale=5.7890625
|
|
60
|
+
n=5, scale=7.05
|
|
61
|
+
n=6, scale=7.046875
|
|
62
|
+
n=7, scale=7.89583333333
|
|
63
|
+
n=8, scale=8.41145833333
|
|
64
|
+
n=9, scale=9.21354166667
|
|
65
|
+
n=10, scale=9.33854166667
|
|
66
|
+
|
|
67
|
+
method="central", order=2, x_values=[0.1, 0.5, 1.0, 5, 10, 50]:
|
|
68
|
+
n=1, mean scale=2.7806603773584904, median scale=3.0
|
|
69
|
+
n=2, mean scale=4.75, median scale=4.0
|
|
70
|
+
n=3, mean scale=5.2334905660377355, median scale=4.75
|
|
71
|
+
n=4, mean scale=5.8046875, median scale=6.0
|
|
72
|
+
n=5, mean scale=7.05, median scale=6.5
|
|
73
|
+
n=6, mean scale=7.020833333333333, median scale=7.625
|
|
74
|
+
n=7, mean scale=7.458333333333333, median scale=7.75
|
|
75
|
+
n=8, mean scale=8.510416666666666, median scale=9.5
|
|
76
|
+
n=9, mean scale=8.328125, median scale=9.0
|
|
77
|
+
n=10, mean scale=9.265625, median scale=10.25
|
|
78
|
+
|
|
79
|
+
Default scale with method="central", order=2, x_values=[0.1, 0.5, 1.0, 5, 10, 50]:
|
|
80
|
+
n=1, scale=2.5
|
|
81
|
+
n=2, scale=3.8
|
|
82
|
+
n=3, scale=5.1
|
|
83
|
+
n=4, scale=6.4
|
|
84
|
+
n=5, scale=7.7
|
|
85
|
+
n=6, scale=9.0
|
|
86
|
+
n=7, scale=10.3
|
|
87
|
+
n=8, scale=11.6
|
|
88
|
+
n=9, scale=12.9
|
|
89
|
+
n=10, scale=14.200000000000001
|
|
90
|
+
|
|
91
|
+
"""
|
|
92
|
+
|
|
93
|
+
from __future__ import absolute_import, division, print_function
|
|
94
|
+
|
|
95
|
+
import matplotlib.pyplot as plt
|
|
96
|
+
import numpy as np
|
|
97
|
+
|
|
98
|
+
from numdifftools import Derivative
|
|
99
|
+
from numdifftools.example_functions import function_names, get_function
|
|
100
|
+
from numdifftools.step_generators import MinStepGenerator, default_scale
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
def plot_error(scales, relativ_error, scale0, title="", label=""):
|
|
104
|
+
plt.semilogy(scales, relativ_error, label=label)
|
|
105
|
+
plt.vlines(scale0, np.nanmin(relativ_error), 1)
|
|
106
|
+
plt.xlabel("scales")
|
|
107
|
+
plt.ylabel("Relative error")
|
|
108
|
+
plt.title(title)
|
|
109
|
+
plt.legend(frameon=False, framealpha=0.5)
|
|
110
|
+
plt.axis([min(scales), max(scales), np.nanmin(relativ_error), 1])
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
def _compute_relative_errors(x, dfun, fd, scales):
|
|
114
|
+
t = []
|
|
115
|
+
for scale in scales:
|
|
116
|
+
fd.step.scale = scale
|
|
117
|
+
try:
|
|
118
|
+
val = fd(x)
|
|
119
|
+
except Exception:
|
|
120
|
+
val = np.nan
|
|
121
|
+
t.append(val)
|
|
122
|
+
|
|
123
|
+
t = np.array(t)
|
|
124
|
+
tt = dfun(x)
|
|
125
|
+
relativ_errors = np.abs(t - tt) / (np.maximum(np.abs(tt), 1)) + 1e-16
|
|
126
|
+
return relativ_errors
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
def benchmark(x=0.0001, dfun=None, fd=None, name="", scales=None, show_plot=True):
|
|
130
|
+
if scales is None:
|
|
131
|
+
scales = np.arange(1.0, 35, 0.25)
|
|
132
|
+
|
|
133
|
+
n, method, order = fd.n, fd.method, fd.order
|
|
134
|
+
|
|
135
|
+
if dfun is None:
|
|
136
|
+
return {
|
|
137
|
+
"n": n,
|
|
138
|
+
"order": order,
|
|
139
|
+
"method": method,
|
|
140
|
+
"fun": name,
|
|
141
|
+
"error": np.nan,
|
|
142
|
+
"scale": np.nan,
|
|
143
|
+
"x": np.nan,
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
relativ_errors = _compute_relative_errors(x, dfun, fd, scales)
|
|
147
|
+
|
|
148
|
+
if not np.isfinite(relativ_errors).any():
|
|
149
|
+
return {"n": n, "order": order, "method": method, "fun": name, "error": np.nan, "scale": np.nan}
|
|
150
|
+
if show_plot:
|
|
151
|
+
txt = ["", "1'st", "2'nd", "3'rd", "4'th", "5'th", "6'th", "7th"] + [
|
|
152
|
+
"%d'th" % i for i in range(8, 25)
|
|
153
|
+
]
|
|
154
|
+
title = "The %s derivative using %s, order=%d" % (txt[n], method, order)
|
|
155
|
+
scale0 = default_scale(method, n, order)
|
|
156
|
+
plot_error(scales, relativ_errors, scale0, title, label=name)
|
|
157
|
+
|
|
158
|
+
i = np.nanargmin(relativ_errors)
|
|
159
|
+
error = float("{:.3g}".format(relativ_errors[i]))
|
|
160
|
+
return {"n": n, "order": order, "method": method, "fun": name, "error": error, "scale": scales[i], "x": x}
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
def _print_summary(method, order, x_values, scales):
|
|
164
|
+
print(scales)
|
|
165
|
+
header = 'method="{}", order={}, x_values={}:'.format(method, order, str(x_values))
|
|
166
|
+
print(header)
|
|
167
|
+
for n in scales:
|
|
168
|
+
print(
|
|
169
|
+
"n={}, mean scale={:.2f}, median scale={:.2f}".format(n, np.mean(scales[n]), np.median(scales[n]))
|
|
170
|
+
)
|
|
171
|
+
|
|
172
|
+
print("Default scale with " + header)
|
|
173
|
+
for n in scales:
|
|
174
|
+
print("n={}, scale={:.2f}".format(n, default_scale(method, n, order)))
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
def run_all_benchmarks(method="forward", order=4, x_values=(0.1, 0.5, 1.0, 5), n_max=11, show_plot=True):
|
|
178
|
+
epsilon = MinStepGenerator(base_step=None, scale=None, step_nom=None, num_extrap=0)
|
|
179
|
+
|
|
180
|
+
scales = {}
|
|
181
|
+
for n in range(1, n_max):
|
|
182
|
+
plt.figure(n)
|
|
183
|
+
scale_n = scales.setdefault(n, [])
|
|
184
|
+
# for (name, x) in itertools.product( function_names, x_values):
|
|
185
|
+
for name in function_names:
|
|
186
|
+
fun0, dfun = get_function(name, n)
|
|
187
|
+
if dfun is None:
|
|
188
|
+
continue
|
|
189
|
+
fd = Derivative(fun0, step=epsilon, method=method, n=n, order=order)
|
|
190
|
+
for x in x_values:
|
|
191
|
+
r = benchmark(x=x, dfun=dfun, fd=fd, name=name, scales=None, show_plot=show_plot)
|
|
192
|
+
print(r)
|
|
193
|
+
scale = r["scale"]
|
|
194
|
+
if np.isfinite(scale):
|
|
195
|
+
scale_n.append(scale)
|
|
196
|
+
|
|
197
|
+
plt.vlines(np.mean(scale_n), 1e-12, 1, "r", linewidth=3)
|
|
198
|
+
plt.vlines(np.median(scale_n), 1e-12, 1, "b", linewidth=3)
|
|
199
|
+
|
|
200
|
+
_print_summary(method, order, x_values, scales)
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
if __name__ == "__main__":
|
|
204
|
+
run_all_benchmarks(
|
|
205
|
+
method="complex",
|
|
206
|
+
order=2,
|
|
207
|
+
x_values=[0.1, 50], # 0.1, 0.5, 1.0, 5, 10, 50,],
|
|
208
|
+
n_max=11,
|
|
209
|
+
)
|
|
210
|
+
plt.show()
|