prtools 1.3.0__tar.gz → 1.3.1__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.
Files changed (27) hide show
  1. {prtools-1.3.0/prtools.egg-info → prtools-1.3.1}/PKG-INFO +1 -1
  2. {prtools-1.3.0 → prtools-1.3.1}/prtools/__init__.py +1 -1
  3. prtools-1.3.1/prtools/backend/__init__.py +19 -0
  4. prtools-1.3.1/prtools/backend/_base.py +7 -0
  5. prtools-1.3.1/prtools/backend/jax.py +130 -0
  6. prtools-1.3.1/prtools/backend/numpy.py +13 -0
  7. {prtools-1.3.0 → prtools-1.3.1/prtools.egg-info}/PKG-INFO +1 -1
  8. {prtools-1.3.0 → prtools-1.3.1}/prtools.egg-info/SOURCES.txt +4 -0
  9. {prtools-1.3.0 → prtools-1.3.1}/pyproject.toml +0 -3
  10. {prtools-1.3.0 → prtools-1.3.1}/LICENSE +0 -0
  11. {prtools-1.3.0 → prtools-1.3.1}/NOTICE +0 -0
  12. {prtools-1.3.0 → prtools-1.3.1}/README.rst +0 -0
  13. {prtools-1.3.0 → prtools-1.3.1}/prtools/_backend.py +0 -0
  14. {prtools-1.3.0 → prtools-1.3.1}/prtools/array.py +0 -0
  15. {prtools-1.3.0 → prtools-1.3.1}/prtools/cost.py +0 -0
  16. {prtools-1.3.0 → prtools-1.3.1}/prtools/fourier.py +0 -0
  17. {prtools-1.3.0 → prtools-1.3.1}/prtools/misc.py +0 -0
  18. {prtools-1.3.0 → prtools-1.3.1}/prtools/segmented.py +0 -0
  19. {prtools-1.3.0 → prtools-1.3.1}/prtools/shape.py +0 -0
  20. {prtools-1.3.0 → prtools-1.3.1}/prtools/sparse.py +0 -0
  21. {prtools-1.3.0 → prtools-1.3.1}/prtools/stats.py +0 -0
  22. {prtools-1.3.0 → prtools-1.3.1}/prtools/zernike.py +0 -0
  23. {prtools-1.3.0 → prtools-1.3.1}/prtools.egg-info/dependency_links.txt +0 -0
  24. {prtools-1.3.0 → prtools-1.3.1}/prtools.egg-info/requires.txt +0 -0
  25. {prtools-1.3.0 → prtools-1.3.1}/prtools.egg-info/top_level.txt +0 -0
  26. {prtools-1.3.0 → prtools-1.3.1}/setup.cfg +0 -0
  27. {prtools-1.3.0 → prtools-1.3.1}/tests/test_array.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: prtools
3
- Version: 1.3.0
3
+ Version: 1.3.1
4
4
  Summary: Utility functions for image-based phase retrieval
5
5
  Author: Andy Kee
6
6
  License: MIT License
@@ -1,4 +1,4 @@
1
- __version__ = '1.3.0'
1
+ __version__ = '1.3.1'
2
2
 
3
3
  from prtools._backend import __backend__, use
4
4
 
@@ -0,0 +1,19 @@
1
+ import importlib
2
+
3
+
4
+ class BackendRegistry:
5
+
6
+ _BUILTIN_BACKEND = ['numpy', 'jax']
7
+
8
+ def _get_backend_module(self, backend):
9
+ return importlib.import_module(f'.{backend}', 'prtools.backend')
10
+
11
+ def load_numpy(self, backend):
12
+ backend = self._get_backend_module(backend)
13
+ return backend.Numpy()
14
+
15
+ def load_scipy(self, backend):
16
+ return self._get_backend_module(backend).Scipy()
17
+
18
+
19
+ registry = BackendRegistry()
@@ -0,0 +1,7 @@
1
+
2
+ class _BackendLibrary:
3
+ def __init__(self, module):
4
+ self.module = module
5
+
6
+ def __getattr__(self, name):
7
+ return getattr(self.module, name)
@@ -0,0 +1,130 @@
1
+ import importlib
2
+ from typing import NamedTuple
3
+
4
+ from ._base import _BackendLibrary
5
+ from prtools import __backend__
6
+ from prtools._backend import numpy as np
7
+
8
+
9
+ class Numpy(_BackendLibrary):
10
+ def __init__(self):
11
+ super().__init__(importlib.import_module('jax.numpy'))
12
+
13
+ def broadcast_to(self, array, shape):
14
+ # jax broadcast_to expects an array input
15
+ array = self.module.asarray(array)
16
+ return self.module.broadcast_to(array, shape)
17
+
18
+ def dot(self, a, b, out=None):
19
+ # jax.numpy.dot doesn't support the `out` parameter so we ignore it
20
+ return self.module.dot(a, b)
21
+
22
+ def max(self, a, *args, **kwargs):
23
+ # jax max expects an array input
24
+ array = self.module.asarray(a)
25
+ return self.module.max(array, *args, **kwargs)
26
+
27
+ def multiply(self, a, b, out=None):
28
+ # jax.numpy.multiply doesn't support the `out` parameter so we
29
+ # ignore it
30
+ return self.module.multiply(a, b)
31
+
32
+ def divide(self, a, b, out=None):
33
+ # jax.numpy.divide doesn't support the `out` parameter so we
34
+ # ignore it
35
+ return self.module.divide(a, b)
36
+
37
+
38
+ class Scipy(_BackendLibrary):
39
+ def __init__(self):
40
+ super().__init__(importlib.import_module('jax.scipy'))
41
+
42
+
43
+ class OptimizeResult(dict):
44
+ """Represents the optimization result.
45
+
46
+ Attributes
47
+ ----------
48
+ x : ndarray
49
+ The solution of the optimization.
50
+
51
+ """
52
+
53
+ def __init__(self):
54
+ super().__init__()
55
+
56
+ #def __getattr__(self, name):
57
+ # try:
58
+ # return self[name]
59
+ # except KeyError as e:
60
+ # raise AttributeError(name) from e
61
+
62
+ #__setattr__ = dict.__setitem__
63
+ #__delattr__ = dict.__delitem__
64
+
65
+
66
+ def lbfgs(fun, x0, tol, maxiter, callback=None):
67
+ """Minimize a scalar function of one or more variables using the L-BFGS
68
+ algorithm
69
+
70
+ Parameters
71
+ ----------
72
+ fun : callable
73
+ The objective function to be minimied
74
+ x0 : array_like
75
+ Initial starting guess
76
+ tol : float
77
+ Termination tolerance
78
+ maxiter : int
79
+ Maximum number of iterations
80
+ callback : callable, optional
81
+ Not currently implemented
82
+
83
+ Returns
84
+ -------
85
+ final_params :
86
+
87
+ final_state :
88
+
89
+ """
90
+ if __backend__ != 'jax':
91
+ raise RuntimeError('JAX backend must be selected')
92
+
93
+ try:
94
+ import jax
95
+ import optax
96
+ import optax.tree_utils as otu
97
+ except ImportError as error:
98
+ raise ImportError('lbfgs requires jax and optax') from error
99
+
100
+ opt = optax.lbfgs()
101
+ value_and_grad_fun = optax.value_and_grad_from_state(fun)
102
+
103
+ def step(carry):
104
+ params, state = carry
105
+ value, grad = value_and_grad_fun(params, state=state)
106
+ updates, state = opt.update(
107
+ grad, state, params, value=value, grad=grad, value_fn=fun,
108
+ )
109
+ if callback:
110
+ res = {}
111
+ res['x'] = params
112
+ res['grad'] = grad
113
+ res['fun'] = value
114
+ res['nit'] = otu.tree_get(state, 'count')
115
+ jax.debug.callback(callback, res)
116
+ params = optax.apply_updates(params, updates)
117
+ return params, state
118
+
119
+ def continuing_criterion(carry):
120
+ _, state = carry
121
+ iter_num = otu.tree_get(state, 'count')
122
+ grad = otu.tree_get(state, 'grad')
123
+ err = otu.tree_l2_norm(grad)
124
+ return (iter_num == 0) | ((iter_num < maxiter) & (err >= tol))
125
+
126
+ init_carry = (x0, opt.init(x0))
127
+ final_params, final_state = jax.lax.while_loop(
128
+ continuing_criterion, step, init_carry
129
+ )
130
+ return final_params, final_state
@@ -0,0 +1,13 @@
1
+ from ._base import _BackendLibrary
2
+
3
+
4
+ class Numpy(_BackendLibrary):
5
+ def __init__(self):
6
+ import numpy
7
+ super().__init__(numpy)
8
+
9
+
10
+ class Scipy(_BackendLibrary):
11
+ def __init__(self):
12
+ import scipy
13
+ super().__init__(scipy)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: prtools
3
- Version: 1.3.0
3
+ Version: 1.3.1
4
4
  Summary: Utility functions for image-based phase retrieval
5
5
  Author: Andy Kee
6
6
  License: MIT License
@@ -18,4 +18,8 @@ prtools.egg-info/SOURCES.txt
18
18
  prtools.egg-info/dependency_links.txt
19
19
  prtools.egg-info/requires.txt
20
20
  prtools.egg-info/top_level.txt
21
+ prtools/backend/__init__.py
22
+ prtools/backend/_base.py
23
+ prtools/backend/jax.py
24
+ prtools/backend/numpy.py
21
25
  tests/test_array.py
@@ -36,8 +36,5 @@ Documentation = "https://andykee.github.io/prtools/"
36
36
  [project.optional-dependencies]
37
37
  jax = ["jax", "optax"]
38
38
 
39
- [tool.setuptools]
40
- packages = ["prtools"]
41
-
42
39
  [tool.setuptools.dynamic]
43
40
  version = {attr = "prtools.__version__"}
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes