prtools 1.4.1__tar.gz → 2.0.0__tar.gz
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.
- {prtools-1.4.1/prtools.egg-info → prtools-2.0.0}/PKG-INFO +2 -1
- {prtools-1.4.1 → prtools-2.0.0}/prtools/__init__.py +15 -4
- prtools-2.0.0/prtools/_array_api.py +105 -0
- {prtools-1.4.1 → prtools-2.0.0}/prtools/array.py +266 -197
- {prtools-1.4.1 → prtools-2.0.0}/prtools/convolve.py +70 -40
- {prtools-1.4.1 → prtools-2.0.0}/prtools/cost.py +25 -24
- {prtools-1.4.1 → prtools-2.0.0}/prtools/fourier.py +34 -57
- {prtools-1.4.1 → prtools-2.0.0}/prtools/jax.py +16 -81
- {prtools-1.4.1 → prtools-2.0.0}/prtools/misc.py +3 -2
- prtools-2.0.0/prtools/morphology.py +435 -0
- {prtools-1.4.1 → prtools-2.0.0}/prtools/segmented.py +2 -1
- {prtools-1.4.1 → prtools-2.0.0}/prtools/shape.py +13 -10
- {prtools-1.4.1 → prtools-2.0.0}/prtools/stats.py +106 -19
- {prtools-1.4.1 → prtools-2.0.0}/prtools/zernike.py +4 -7
- {prtools-1.4.1 → prtools-2.0.0/prtools.egg-info}/PKG-INFO +2 -1
- {prtools-1.4.1 → prtools-2.0.0}/prtools.egg-info/SOURCES.txt +4 -5
- {prtools-1.4.1 → prtools-2.0.0}/prtools.egg-info/requires.txt +1 -0
- {prtools-1.4.1 → prtools-2.0.0}/pyproject.toml +1 -0
- prtools-2.0.0/tests/test_array.py +112 -0
- prtools-2.0.0/tests/test_convolve.py +68 -0
- prtools-2.0.0/tests/test_fourier.py +87 -0
- prtools-2.0.0/tests/test_jax.py +16 -0
- prtools-1.4.1/prtools/backend/__init__.py +0 -105
- prtools-1.4.1/prtools/backend/_base.py +0 -7
- prtools-1.4.1/prtools/backend/_jax.py +0 -56
- prtools-1.4.1/prtools/backend/_numpy.py +0 -13
- prtools-1.4.1/tests/test_array.py +0 -81
- prtools-1.4.1/tests/test_convolve.py +0 -75
- prtools-1.4.1/tests/test_fourier.py +0 -85
- {prtools-1.4.1 → prtools-2.0.0}/LICENSE +0 -0
- {prtools-1.4.1 → prtools-2.0.0}/NOTICE +0 -0
- {prtools-1.4.1 → prtools-2.0.0}/README.rst +0 -0
- {prtools-1.4.1 → prtools-2.0.0}/prtools/sparse.py +0 -0
- {prtools-1.4.1 → prtools-2.0.0}/prtools.egg-info/dependency_links.txt +0 -0
- {prtools-1.4.1 → prtools-2.0.0}/prtools.egg-info/top_level.txt +0 -0
- {prtools-1.4.1 → prtools-2.0.0}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: prtools
|
|
3
|
-
Version:
|
|
3
|
+
Version: 2.0.0
|
|
4
4
|
Summary: Utility functions for image-based phase retrieval
|
|
5
5
|
Author: Andy Kee
|
|
6
6
|
License: MIT License
|
|
@@ -42,6 +42,7 @@ License-File: LICENSE
|
|
|
42
42
|
License-File: NOTICE
|
|
43
43
|
Requires-Dist: numpy
|
|
44
44
|
Requires-Dist: scipy
|
|
45
|
+
Requires-Dist: array_api_compat
|
|
45
46
|
Provides-Extra: jax
|
|
46
47
|
Requires-Dist: jax; extra == "jax"
|
|
47
48
|
Requires-Dist: optax; extra == "jax"
|
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
__version__ = '
|
|
1
|
+
__version__ = '2.0.0'
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
|
|
4
|
+
from prtools._array_api import use
|
|
4
5
|
|
|
5
6
|
from prtools.array import (
|
|
6
7
|
centroid,
|
|
7
8
|
pad,
|
|
8
|
-
|
|
9
|
+
crop,
|
|
9
10
|
boundary,
|
|
10
11
|
rebin,
|
|
11
12
|
rescale,
|
|
@@ -40,6 +41,13 @@ from prtools.misc import (
|
|
|
40
41
|
find_wrapped
|
|
41
42
|
)
|
|
42
43
|
|
|
44
|
+
from prtools.morphology import (
|
|
45
|
+
binary_dilation,
|
|
46
|
+
binary_erosion,
|
|
47
|
+
binary_opening,
|
|
48
|
+
binary_closing
|
|
49
|
+
)
|
|
50
|
+
|
|
43
51
|
from prtools.segmented import hex_segments
|
|
44
52
|
|
|
45
53
|
from prtools.shape import (
|
|
@@ -64,7 +72,10 @@ from prtools.stats import (
|
|
|
64
72
|
ee,
|
|
65
73
|
pv,
|
|
66
74
|
rms,
|
|
67
|
-
|
|
75
|
+
nanpv,
|
|
76
|
+
nanrms,
|
|
77
|
+
radial_avg,
|
|
78
|
+
teng
|
|
68
79
|
)
|
|
69
80
|
|
|
70
81
|
from prtools.zernike import (
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import enum
|
|
2
|
+
import warnings
|
|
3
|
+
|
|
4
|
+
import array_api_compat
|
|
5
|
+
from array_api_compat import is_jax_namespace as is_jax
|
|
6
|
+
import numpy as np
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def use(backend):
|
|
10
|
+
msg = 'prtools.use() was deprecated in prtools v2.0.0. The numerical ' \
|
|
11
|
+
'backend is now selected automatically depending on input array ' \
|
|
12
|
+
'type or by specifying the xp argument (when available). '
|
|
13
|
+
warnings.warn(msg + 'In a future prtools release this will be an error.',
|
|
14
|
+
category=DeprecationWarning, stacklevel=2)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class _ArrayCoerce(enum.Enum):
|
|
18
|
+
none = 0
|
|
19
|
+
numpy = 1
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def _array_cls(array):
|
|
23
|
+
if issubclass(type(array), list | tuple):
|
|
24
|
+
return _ArrayCoerce.numpy
|
|
25
|
+
else:
|
|
26
|
+
return _ArrayCoerce.none
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def array_namespace(*xs):
|
|
30
|
+
"""Get the array API compatible namespace for the arrays `xs`
|
|
31
|
+
|
|
32
|
+
Notes
|
|
33
|
+
-----
|
|
34
|
+
This function is a wrapper arpund `array_api_compat.array_namespace`. It
|
|
35
|
+
is inspired by the scipy function of the same name.
|
|
36
|
+
"""
|
|
37
|
+
arrays = [np.array(x) if _array_cls(x) is _ArrayCoerce.numpy else x for x in xs]
|
|
38
|
+
return array_api_compat.array_namespace(*arrays)
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def scipy_namespace(xp):
|
|
42
|
+
"""Return the `scipy`-like namespace corresponding to the array namespace
|
|
43
|
+
``xp``.
|
|
44
|
+
"""
|
|
45
|
+
if is_jax(xp):
|
|
46
|
+
import jax
|
|
47
|
+
return jax.scipy
|
|
48
|
+
else:
|
|
49
|
+
import scipy
|
|
50
|
+
return scipy
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def xp_multi_dot_three(a, b, c, axes, out, xp=None):
|
|
54
|
+
if xp is None:
|
|
55
|
+
xp = array_namespace(a, b, c)
|
|
56
|
+
|
|
57
|
+
if is_jax(xp):
|
|
58
|
+
# a few notes:
|
|
59
|
+
# * while numpy-based implementation of this method is based on
|
|
60
|
+
# np.matmul, jax.numpy.matmul doesn't implement the axes argument so
|
|
61
|
+
# we have to use jax.numpy.linalg.multi_dot instead
|
|
62
|
+
# * the implementation used here supports b with ndim in (2, 3)
|
|
63
|
+
# iterating over any of the 3 axes when b.ndim == 3
|
|
64
|
+
# * jax.vmap handles the case when b.ndim == 3 compared with the numpy
|
|
65
|
+
# equivalent of this function which does everything within the
|
|
66
|
+
# confines of matmul using the axes argument
|
|
67
|
+
if b.ndim == 2:
|
|
68
|
+
return xp.linalg.multi_dot((a, b, c))
|
|
69
|
+
else:
|
|
70
|
+
import jax
|
|
71
|
+
iter_axis = _iter_axis(axes)
|
|
72
|
+
return jax.vmap(_multi_dot, in_axes=(None, iter_axis, None), out_axes=iter_axis)(a, b, c)
|
|
73
|
+
else:
|
|
74
|
+
# a few notes:
|
|
75
|
+
# * this method is similar to np.linalg.multi_dot although it is less
|
|
76
|
+
# general - here we only consider the matrix triple product used as
|
|
77
|
+
# a part of prtools.dft2
|
|
78
|
+
# * because we use np.matmul instead of np.linalg.multi_dot, we can
|
|
79
|
+
# take advantage of broadcasting a and c when b.ndim = 3. This
|
|
80
|
+
# eliminates a for loop in the code
|
|
81
|
+
# * the implementation used here supports b with ndim in (2, 3)
|
|
82
|
+
# iterating over any of the 3 axes when b.ndim == 3
|
|
83
|
+
# * the implementation used here is actually slightly faster than
|
|
84
|
+
# an equivalent call to np.linalg.multi_dot when b.ndim == 2
|
|
85
|
+
# * np.linalg.multi_dot chooses the fastest multiplication order from
|
|
86
|
+
# [(ab)c, a(bc)] depending on the shapes of a, b, and c. There is no
|
|
87
|
+
# difference when computing the dft because both a and c are square
|
|
88
|
+
# matrices
|
|
89
|
+
ab = xp.matmul(a, b, axes=[(0, 1), axes, axes])
|
|
90
|
+
out = xp.matmul(ab, c, axes=[axes, (0, 1), axes], out=out)
|
|
91
|
+
return out
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def _multi_dot(a, b, c):
|
|
95
|
+
# wrapper function to support vmap call signature
|
|
96
|
+
xp = array_namespace(a, b, c)
|
|
97
|
+
return xp.linalg.multi_dot((a, b, c))
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
def _iter_axis(axes):
|
|
101
|
+
# pure Python to avoid dealing with JAX array mutability issues
|
|
102
|
+
mask = [0, 1, 2]
|
|
103
|
+
for ax in axes:
|
|
104
|
+
mask[ax] = None
|
|
105
|
+
return [ax for ax in mask if ax is not None][0]
|