invrs-opt 0.3.2__py3-none-any.whl → 0.5.0__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.
- invrs_opt/__init__.py +1 -1
- invrs_opt/experimental/__init__.py +0 -0
- invrs_opt/experimental/client.py +152 -0
- invrs_opt/experimental/labels.py +23 -0
- invrs_opt/lbfgsb/lbfgsb.py +72 -8
- {invrs_opt-0.3.2.dist-info → invrs_opt-0.5.0.dist-info}/METADATA +4 -2
- invrs_opt-0.5.0.dist-info/RECORD +14 -0
- {invrs_opt-0.3.2.dist-info → invrs_opt-0.5.0.dist-info}/WHEEL +1 -1
- invrs_opt-0.3.2.dist-info/RECORD +0 -11
- {invrs_opt-0.3.2.dist-info → invrs_opt-0.5.0.dist-info}/LICENSE +0 -0
- {invrs_opt-0.3.2.dist-info → invrs_opt-0.5.0.dist-info}/top_level.txt +0 -0
invrs_opt/__init__.py
CHANGED
File without changes
|
@@ -0,0 +1,152 @@
|
|
1
|
+
"""Defines basic client optimizers for use with an optimization service.
|
2
|
+
|
3
|
+
Copyright (c) 2023 The INVRS-IO authors.
|
4
|
+
"""
|
5
|
+
|
6
|
+
import json
|
7
|
+
import requests
|
8
|
+
import time
|
9
|
+
from typing import Any, Dict, Optional
|
10
|
+
|
11
|
+
from totypes import json_utils
|
12
|
+
|
13
|
+
from invrs_opt import base
|
14
|
+
from invrs_opt.experimental import labels
|
15
|
+
|
16
|
+
|
17
|
+
PyTree = Any
|
18
|
+
StateToken = str
|
19
|
+
|
20
|
+
SESSION = None
|
21
|
+
SERVER_ADDRESS = None
|
22
|
+
|
23
|
+
|
24
|
+
def login(server_address: str) -> None:
|
25
|
+
"""Set the global server address and create a requests session."""
|
26
|
+
global SESSION
|
27
|
+
global SERVER_ADDRESS
|
28
|
+
SESSION = requests.Session()
|
29
|
+
SERVER_ADDRESS = server_address
|
30
|
+
|
31
|
+
|
32
|
+
def optimizer_client(
|
33
|
+
algorithm: str,
|
34
|
+
hparams: Dict[str, Any],
|
35
|
+
server_address: Optional[str],
|
36
|
+
session: Optional[requests.Session],
|
37
|
+
) -> base.Optimizer:
|
38
|
+
"""Generic optimizer class."""
|
39
|
+
|
40
|
+
if server_address is None:
|
41
|
+
if SERVER_ADDRESS is None:
|
42
|
+
raise ValueError(
|
43
|
+
"Argument `server_address` and the global `SERVER_ADDRESS` cannot "
|
44
|
+
"both be `None`. Use the `login` method to set the global, or "
|
45
|
+
"explicitly provide a value."
|
46
|
+
)
|
47
|
+
if session is None:
|
48
|
+
if SESSION is None:
|
49
|
+
raise ValueError(
|
50
|
+
"Argument `session` and the global `SESSION` cannot "
|
51
|
+
"both be `None`. Use the `login` method to set the global, or "
|
52
|
+
"explicitly provide a value."
|
53
|
+
)
|
54
|
+
session = SESSION
|
55
|
+
|
56
|
+
opt_config = {
|
57
|
+
labels.ALGORITHM: algorithm,
|
58
|
+
labels.HPARAMS: hparams,
|
59
|
+
}
|
60
|
+
|
61
|
+
def init_fn(params: PyTree) -> StateToken:
|
62
|
+
"""Handles 'init' requests."""
|
63
|
+
serialized_data = json_utils.json_from_pytree(
|
64
|
+
dict(opt_config=opt_config, data={"params": params})
|
65
|
+
)
|
66
|
+
post_response = session.post(
|
67
|
+
f"{SERVER_ADDRESS}/{labels.ROUTE_INIT}/", data=serialized_data
|
68
|
+
)
|
69
|
+
|
70
|
+
if not post_response.status_code == 200:
|
71
|
+
raise requests.RequestException(post_response.text)
|
72
|
+
response = json.loads(post_response.text)
|
73
|
+
new_state_token: str = response[labels.STATE_TOKEN]
|
74
|
+
return new_state_token
|
75
|
+
|
76
|
+
def update_fn(
|
77
|
+
*,
|
78
|
+
grad: PyTree,
|
79
|
+
value: float,
|
80
|
+
params: PyTree,
|
81
|
+
state: StateToken,
|
82
|
+
) -> StateToken:
|
83
|
+
"""Handles 'update' requests."""
|
84
|
+
state_token = state
|
85
|
+
del state
|
86
|
+
serialized_data = json_utils.json_from_pytree(
|
87
|
+
{
|
88
|
+
labels.OPT_CONFIG: opt_config,
|
89
|
+
labels.DATA: {
|
90
|
+
labels.PARAMS: params,
|
91
|
+
labels.VALUE: value,
|
92
|
+
labels.GRAD: grad,
|
93
|
+
labels.STATE_TOKEN: state_token,
|
94
|
+
},
|
95
|
+
}
|
96
|
+
)
|
97
|
+
post_response = session.post(
|
98
|
+
f"{SERVER_ADDRESS}/{labels.ROUTE_UPDATE}/{state_token}/",
|
99
|
+
data=serialized_data,
|
100
|
+
)
|
101
|
+
|
102
|
+
if not post_response.status_code == 200:
|
103
|
+
raise requests.RequestException(post_response.text)
|
104
|
+
response = json.loads(post_response.text)
|
105
|
+
new_state_token: str = response[labels.STATE_TOKEN]
|
106
|
+
return new_state_token
|
107
|
+
|
108
|
+
def params_fn(
|
109
|
+
state: StateToken,
|
110
|
+
timeout: float = 60.0,
|
111
|
+
poll_interval: float = 0.1,
|
112
|
+
) -> PyTree:
|
113
|
+
"""Handles 'params' requests."""
|
114
|
+
state_token = state
|
115
|
+
del state
|
116
|
+
assert timeout >= poll_interval
|
117
|
+
start_time = time.time()
|
118
|
+
while time.time() < start_time + timeout:
|
119
|
+
get_response = session.get(
|
120
|
+
f"{SERVER_ADDRESS}/{labels.ROUTE_PARAMS}/{state_token}"
|
121
|
+
)
|
122
|
+
if get_response.status_code == 200:
|
123
|
+
break
|
124
|
+
elif get_response.status_code == 404 and get_response.text.endswith(
|
125
|
+
labels.MESSAGE_STATE_NOT_READY.format(state_token)
|
126
|
+
):
|
127
|
+
time.sleep(poll_interval)
|
128
|
+
else:
|
129
|
+
raise requests.RequestException(get_response.text)
|
130
|
+
|
131
|
+
if not get_response.status_code == 200:
|
132
|
+
raise requests.Timeout("Timed out while waiting for params.")
|
133
|
+
response = json.loads(get_response.text)
|
134
|
+
return json_utils.pytree_from_json(response[labels.PARAMS])
|
135
|
+
|
136
|
+
return base.Optimizer(init=init_fn, update=update_fn, params=params_fn)
|
137
|
+
|
138
|
+
|
139
|
+
# -----------------------------------------------------------------------------
|
140
|
+
# Specific optimizers implemented here.
|
141
|
+
# -----------------------------------------------------------------------------
|
142
|
+
|
143
|
+
|
144
|
+
def lbfgsb(maxcor: int = 20, line_search_max_steps: int = 100) -> base.Optimizer:
|
145
|
+
"""Optimizer implementing the L-BFGS-B scheme."""
|
146
|
+
hparams = {
|
147
|
+
"maxcor": maxcor,
|
148
|
+
"line_search_max_steps": line_search_max_steps,
|
149
|
+
}
|
150
|
+
return optimizer_client(
|
151
|
+
algorithm="lbfgsb", hparams=hparams, server_address=None, session=None
|
152
|
+
)
|
@@ -0,0 +1,23 @@
|
|
1
|
+
"""Defines labels and messages used in the context of an optimization service.
|
2
|
+
|
3
|
+
Copyright (c) 2023 The INVRS-IO authors.
|
4
|
+
"""
|
5
|
+
|
6
|
+
VALUE = "value"
|
7
|
+
GRAD = "grad"
|
8
|
+
PARAMS = "params"
|
9
|
+
STATE_TOKEN = "state_token"
|
10
|
+
MESSAGE = "message"
|
11
|
+
|
12
|
+
OPT_CONFIG = "opt_config"
|
13
|
+
ALGORITHM = "algorithm"
|
14
|
+
HPARAMS = "hparams"
|
15
|
+
DATA = "data"
|
16
|
+
|
17
|
+
ROUTE_INIT = "init"
|
18
|
+
ROUTE_UPDATE = "update"
|
19
|
+
ROUTE_PARAMS = "params"
|
20
|
+
|
21
|
+
MESSAGE_STATE_NOT_KNOWN = "State token {} was not recognized."
|
22
|
+
MESSAGE_STATE_NOT_READY = "State for token {} is not ready."
|
23
|
+
MESSAGE_STATE_NOT_VALID = "State for token {} is not valid."
|
invrs_opt/lbfgsb/lbfgsb.py
CHANGED
@@ -29,16 +29,16 @@ LbfgsbState = Tuple[PyTree, PyTree, JaxLbfgsbDict]
|
|
29
29
|
# Task message prefixes for the underlying L-BFGS-B implementation.
|
30
30
|
TASK_START = b"START"
|
31
31
|
TASK_FG = b"FG"
|
32
|
+
TASK_CONVERGED = b"CONVERGENCE"
|
32
33
|
|
33
|
-
# Parameters which configure the state update step.
|
34
34
|
UPDATE_IPRINT = -1
|
35
|
-
UPDATE_PGTOL = 0.0
|
36
|
-
UPDATE_FACTR = 0.0
|
37
35
|
|
38
36
|
# Maximum value for the `maxcor` parameter in the L-BFGS-B scheme.
|
39
37
|
MAXCOR_MAX_VALUE = 100
|
40
38
|
MAXCOR_DEFAULT = 20
|
41
39
|
LINE_SEARCH_MAX_STEPS_DEFAULT = 100
|
40
|
+
FTOL_DEFAULT = 0.0
|
41
|
+
GTOL_DEFAULT = 0.0
|
42
42
|
|
43
43
|
# Maps bound scenarios to integers.
|
44
44
|
BOUNDS_MAP: Dict[Tuple[bool, bool], int] = {
|
@@ -54,6 +54,8 @@ FORTRAN_INT = scipy_lbfgsb.types.intvar.dtype
|
|
54
54
|
def lbfgsb(
|
55
55
|
maxcor: int = MAXCOR_DEFAULT,
|
56
56
|
line_search_max_steps: int = LINE_SEARCH_MAX_STEPS_DEFAULT,
|
57
|
+
ftol: float = FTOL_DEFAULT,
|
58
|
+
gtol: float = GTOL_DEFAULT,
|
57
59
|
) -> base.Optimizer:
|
58
60
|
"""Return an optimizer implementing the standard L-BFGS-B algorithm.
|
59
61
|
|
@@ -85,10 +87,17 @@ def lbfgsb(
|
|
85
87
|
While the algorithm can work with pytrees of jax arrays, numpy arrays can
|
86
88
|
also be used. Thus, e.g. the optimizer can directly be used with autograd.
|
87
89
|
|
90
|
+
When the optimization has converged (according to `ftol` or `gtol` criteria), the
|
91
|
+
optimizer simply returns the parameters which obtained the converged result. The
|
92
|
+
convergence can be queried by `is_converged(state)`.
|
93
|
+
|
88
94
|
Args:
|
89
95
|
maxcor: The maximum number of variable metric corrections used to define
|
90
96
|
the limited memory matrix, in the L-BFGS-B scheme.
|
91
97
|
line_search_max_steps: The maximum number of steps in the line search.
|
98
|
+
ftol: Tolerance for stopping criteria based on function values. See scipy
|
99
|
+
documentation for details.
|
100
|
+
gtol: Tolerance for stopping criteria based on gradient.
|
92
101
|
|
93
102
|
Returns:
|
94
103
|
The `base.Optimizer`.
|
@@ -96,6 +105,8 @@ def lbfgsb(
|
|
96
105
|
return transformed_lbfgsb(
|
97
106
|
maxcor=maxcor,
|
98
107
|
line_search_max_steps=line_search_max_steps,
|
108
|
+
ftol=ftol,
|
109
|
+
gtol=gtol,
|
99
110
|
transform_fn=lambda x: x,
|
100
111
|
initialize_latent_fn=lambda x: x,
|
101
112
|
)
|
@@ -105,6 +116,8 @@ def density_lbfgsb(
|
|
105
116
|
beta: float,
|
106
117
|
maxcor: int = MAXCOR_DEFAULT,
|
107
118
|
line_search_max_steps: int = LINE_SEARCH_MAX_STEPS_DEFAULT,
|
119
|
+
ftol: float = FTOL_DEFAULT,
|
120
|
+
gtol: float = GTOL_DEFAULT,
|
108
121
|
) -> base.Optimizer:
|
109
122
|
"""Return an L-BFGS-B optimizer with additional transforms for density arrays.
|
110
123
|
|
@@ -117,11 +130,18 @@ def density_lbfgsb(
|
|
117
130
|
and spacing parameters of the `DensityArray2D`. Where the bounds differ, the
|
118
131
|
density is scaled before the transform is applied, and then unscaled afterwards.
|
119
132
|
|
133
|
+
When the optimization has converged (according to `ftol` or `gtol` criteria), the
|
134
|
+
optimizer simply returns the parameters which obtained the converged result. The
|
135
|
+
convergence can be queried by `is_converged(state)`.
|
136
|
+
|
120
137
|
Args:
|
121
138
|
beta: Determines the steepness of the thresholding.
|
122
139
|
maxcor: The maximum number of variable metric corrections used to define
|
123
140
|
the limited memory matrix, in the L-BFGS-B scheme.
|
124
141
|
line_search_max_steps: The maximum number of steps in the line search.
|
142
|
+
ftol: Tolerance for stopping criteria based on function values. See scipy
|
143
|
+
documentation for details.
|
144
|
+
gtol: Tolerance for stopping criteria based on gradient.
|
125
145
|
|
126
146
|
Returns:
|
127
147
|
The `base.Optimizer`.
|
@@ -164,6 +184,8 @@ def density_lbfgsb(
|
|
164
184
|
return transformed_lbfgsb(
|
165
185
|
maxcor=maxcor,
|
166
186
|
line_search_max_steps=line_search_max_steps,
|
187
|
+
ftol=ftol,
|
188
|
+
gtol=gtol,
|
167
189
|
transform_fn=transform_fn,
|
168
190
|
initialize_latent_fn=initialize_latent_fn,
|
169
191
|
)
|
@@ -172,6 +194,8 @@ def density_lbfgsb(
|
|
172
194
|
def transformed_lbfgsb(
|
173
195
|
maxcor: int,
|
174
196
|
line_search_max_steps: int,
|
197
|
+
ftol: float,
|
198
|
+
gtol: float,
|
175
199
|
transform_fn: Callable[[PyTree], PyTree],
|
176
200
|
initialize_latent_fn: Callable[[PyTree], PyTree],
|
177
201
|
) -> base.Optimizer:
|
@@ -182,10 +206,17 @@ def transformed_lbfgsb(
|
|
182
206
|
`transform_fn`. In the simple case where this is just `lambda x: x` (i.e.
|
183
207
|
the identity), this is equivalent to the standard L-BFGS-B algorithm.
|
184
208
|
|
209
|
+
When the optimization has converged (according to `ftol` or `gtol` criteria), the
|
210
|
+
optimizer simply returns the parameters which obtained the converged result. The
|
211
|
+
convergence can be queried by `is_converged(state)`.
|
212
|
+
|
185
213
|
Args:
|
186
214
|
maxcor: The maximum number of variable metric corrections used to define
|
187
215
|
the limited memory matrix, in the L-BFGS-B scheme.
|
188
216
|
line_search_max_steps: The maximum number of steps in the line search.
|
217
|
+
ftol: Tolerance for stopping criteria based on function values. See scipy
|
218
|
+
documentation for details.
|
219
|
+
gtol: Tolerance for stopping criteria based on gradient.
|
189
220
|
transform_fn: Function which transforms the internal latent parameters to
|
190
221
|
the parameters returned by the optimizer.
|
191
222
|
initialize_latent_fn: Function which computes the initial latent parameters
|
@@ -218,6 +249,8 @@ def transformed_lbfgsb(
|
|
218
249
|
upper_bound=_bound_for_params(upper_bound, params),
|
219
250
|
maxcor=maxcor,
|
220
251
|
line_search_max_steps=line_search_max_steps,
|
252
|
+
ftol=ftol,
|
253
|
+
gtol=gtol,
|
221
254
|
)
|
222
255
|
latent_params = _to_pytree(scipy_lbfgsb_state.x, params)
|
223
256
|
return latent_params, scipy_lbfgsb_state.to_jax()
|
@@ -261,10 +294,12 @@ def transformed_lbfgsb(
|
|
261
294
|
flat_latent_params = jnp.asarray(scipy_lbfgsb_state.x)
|
262
295
|
return flat_latent_params, scipy_lbfgsb_state.to_jax()
|
263
296
|
|
264
|
-
|
297
|
+
_, latent_params, jax_lbfgsb_state = state
|
265
298
|
_, vjp_fn = jax.vjp(transform_fn, latent_params)
|
266
299
|
(latent_grad,) = vjp_fn(grad)
|
267
|
-
flat_latent_grad, unflatten_fn = flatten_util.ravel_pytree(
|
300
|
+
flat_latent_grad, unflatten_fn = flatten_util.ravel_pytree(
|
301
|
+
latent_grad
|
302
|
+
) # type: ignore[no-untyped-call]
|
268
303
|
|
269
304
|
(
|
270
305
|
flat_latent_params,
|
@@ -286,6 +321,11 @@ def transformed_lbfgsb(
|
|
286
321
|
)
|
287
322
|
|
288
323
|
|
324
|
+
def is_converged(state: LbfgsbState) -> jnp.ndarray:
|
325
|
+
"""Returns `True` if the optimization has converged."""
|
326
|
+
return state[2]["converged"]
|
327
|
+
|
328
|
+
|
289
329
|
# ------------------------------------------------------------------------------
|
290
330
|
# Helper functions.
|
291
331
|
# ------------------------------------------------------------------------------
|
@@ -390,8 +430,11 @@ def _example_state(params: PyTree, maxcor: int) -> PyTree:
|
|
390
430
|
float_params = tree_util.tree_map(lambda x: jnp.asarray(x, dtype=float), params)
|
391
431
|
example_jax_lbfgsb_state = dict(
|
392
432
|
x=jnp.zeros(n, dtype=float),
|
433
|
+
converged=jnp.asarray(False),
|
393
434
|
_maxcor=jnp.zeros((), dtype=int),
|
394
435
|
_line_search_max_steps=jnp.zeros((), dtype=int),
|
436
|
+
_ftol=jnp.zeros((), dtype=float),
|
437
|
+
_gtol=jnp.zeros((), dtype=float),
|
395
438
|
_wa=jnp.ones(_wa_size(n=n, maxcor=maxcor), dtype=float),
|
396
439
|
_iwa=jnp.ones(n * 3, dtype=jnp.int32), # Fortran int
|
397
440
|
_task=jnp.zeros(59, dtype=int),
|
@@ -441,10 +484,13 @@ class ScipyLbfgsbState:
|
|
441
484
|
"""
|
442
485
|
|
443
486
|
x: NDArray
|
487
|
+
converged: NDArray
|
444
488
|
# Private attributes correspond to internal variables in the `scipy.optimize.
|
445
489
|
# lbfgsb._minimize_lbfgsb` function.
|
446
490
|
_maxcor: int
|
447
491
|
_line_search_max_steps: int
|
492
|
+
_ftol: NDArray
|
493
|
+
_gtol: NDArray
|
448
494
|
_wa: NDArray
|
449
495
|
_iwa: NDArray
|
450
496
|
_task: NDArray
|
@@ -474,8 +520,11 @@ class ScipyLbfgsbState:
|
|
474
520
|
"""Generates a dictionary of jax arrays defining the state."""
|
475
521
|
return dict(
|
476
522
|
x=jnp.asarray(self.x),
|
523
|
+
converged=jnp.asarray(self.converged),
|
477
524
|
_maxcor=jnp.asarray(self._maxcor),
|
478
525
|
_line_search_max_steps=jnp.asarray(self._line_search_max_steps),
|
526
|
+
_ftol=jnp.asarray(self._ftol),
|
527
|
+
_gtol=jnp.asarray(self._gtol),
|
479
528
|
_wa=jnp.asarray(self._wa),
|
480
529
|
_iwa=jnp.asarray(self._iwa),
|
481
530
|
_task=_array_from_s60_str(self._task),
|
@@ -494,8 +543,11 @@ class ScipyLbfgsbState:
|
|
494
543
|
state_dict = copy.deepcopy(state_dict)
|
495
544
|
return ScipyLbfgsbState(
|
496
545
|
x=onp.asarray(state_dict["x"], dtype=onp.float64),
|
546
|
+
converged=onp.asarray(state_dict["converged"], dtype=bool),
|
497
547
|
_maxcor=int(state_dict["_maxcor"]),
|
498
548
|
_line_search_max_steps=int(state_dict["_line_search_max_steps"]),
|
549
|
+
_ftol=onp.asarray(state_dict["_ftol"], dtype=onp.float64),
|
550
|
+
_gtol=onp.asarray(state_dict["_gtol"], dtype=onp.float64),
|
499
551
|
_wa=onp.asarray(state_dict["_wa"], onp.float64),
|
500
552
|
_iwa=onp.asarray(state_dict["_iwa"], dtype=FORTRAN_INT),
|
501
553
|
_task=_s60_str_from_array(state_dict["_task"]),
|
@@ -516,6 +568,8 @@ class ScipyLbfgsbState:
|
|
516
568
|
upper_bound: ElementwiseBound,
|
517
569
|
maxcor: int,
|
518
570
|
line_search_max_steps: int,
|
571
|
+
ftol: float,
|
572
|
+
gtol: float,
|
519
573
|
) -> "ScipyLbfgsbState":
|
520
574
|
"""Initializes the `ScipyLbfgsbState` for `x0`.
|
521
575
|
|
@@ -526,6 +580,9 @@ class ScipyLbfgsbState:
|
|
526
580
|
maxcor: The maximum number of variable metric corrections used to define
|
527
581
|
the limited memory matrix, in the L-BFGS-B scheme.
|
528
582
|
line_search_max_steps: The maximum number of steps in the line search.
|
583
|
+
ftol: Tolerance for stopping criteria based on function values. See scipy
|
584
|
+
documentation for details.
|
585
|
+
gtol: Tolerance for stopping criteria based on gradient.
|
529
586
|
|
530
587
|
Returns:
|
531
588
|
The `ScipyLbfgsbState`.
|
@@ -556,8 +613,11 @@ class ScipyLbfgsbState:
|
|
556
613
|
wa_size = _wa_size(n=n, maxcor=maxcor)
|
557
614
|
state = ScipyLbfgsbState(
|
558
615
|
x=onp.array(x0, onp.float64),
|
616
|
+
converged=onp.asarray(False),
|
559
617
|
_maxcor=maxcor,
|
560
618
|
_line_search_max_steps=line_search_max_steps,
|
619
|
+
_ftol=onp.asarray(ftol, onp.float64),
|
620
|
+
_gtol=onp.asarray(gtol, onp.float64),
|
561
621
|
_wa=onp.zeros(wa_size, onp.float64),
|
562
622
|
_iwa=onp.zeros(3 * n, FORTRAN_INT),
|
563
623
|
_task=task,
|
@@ -580,12 +640,14 @@ class ScipyLbfgsbState:
|
|
580
640
|
grad: NDArray,
|
581
641
|
value: NDArray,
|
582
642
|
) -> None:
|
583
|
-
"""Performs an in-place update of the `ScipyLbfgsbState
|
643
|
+
"""Performs an in-place update of the `ScipyLbfgsbState` if not converged.
|
584
644
|
|
585
645
|
Args:
|
586
646
|
grad: The function gradient for the current `x`.
|
587
647
|
value: The scalar function value for the current `x`.
|
588
648
|
"""
|
649
|
+
if self.converged:
|
650
|
+
return
|
589
651
|
if grad.shape != self.x.shape:
|
590
652
|
raise ValueError(
|
591
653
|
f"`grad` must have the same shape as attribute `x`, but got shapes "
|
@@ -606,8 +668,8 @@ class ScipyLbfgsbState:
|
|
606
668
|
nbd=self._bound_type,
|
607
669
|
f=value,
|
608
670
|
g=grad,
|
609
|
-
factr=
|
610
|
-
pgtol=
|
671
|
+
factr=self._ftol / onp.finfo(float).eps,
|
672
|
+
pgtol=self._gtol,
|
611
673
|
wa=self._wa,
|
612
674
|
iwa=self._iwa,
|
613
675
|
task=self._task,
|
@@ -619,6 +681,8 @@ class ScipyLbfgsbState:
|
|
619
681
|
maxls=self._line_search_max_steps,
|
620
682
|
)
|
621
683
|
task_str = self._task.tobytes()
|
684
|
+
if task_str.startswith(TASK_CONVERGED):
|
685
|
+
self.converged = onp.asarray(True)
|
622
686
|
if task_str.startswith(TASK_FG):
|
623
687
|
break
|
624
688
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: invrs_opt
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.5.0
|
4
4
|
Summary: Algorithms for inverse design
|
5
5
|
Author-email: "Martin F. Schubert" <mfschubert@gmail.com>
|
6
6
|
Maintainer-email: "Martin F. Schubert" <mfschubert@gmail.com>
|
@@ -33,8 +33,10 @@ License-File: LICENSE
|
|
33
33
|
Requires-Dist: jax
|
34
34
|
Requires-Dist: jaxlib
|
35
35
|
Requires-Dist: numpy
|
36
|
+
Requires-Dist: requests
|
36
37
|
Requires-Dist: scipy
|
37
38
|
Requires-Dist: totypes
|
39
|
+
Requires-Dist: types-requests
|
38
40
|
Provides-Extra: dev
|
39
41
|
Requires-Dist: bump-my-version ; extra == 'dev'
|
40
42
|
Requires-Dist: darglint ; extra == 'dev'
|
@@ -47,7 +49,7 @@ Requires-Dist: pytest-cov ; extra == 'tests'
|
|
47
49
|
Requires-Dist: pytest-subtests ; extra == 'tests'
|
48
50
|
|
49
51
|
# invrs-opt - Optimization algorithms for inverse design
|
50
|
-
`v0.
|
52
|
+
`v0.5.0`
|
51
53
|
|
52
54
|
## Overview
|
53
55
|
|
@@ -0,0 +1,14 @@
|
|
1
|
+
invrs_opt/__init__.py,sha256=SK2nHKhwT60br9D6W8gfJ5Kj11BR3fIdGAEVAJBgH1I,309
|
2
|
+
invrs_opt/base.py,sha256=dSX9QkMPzI8ROxy2cFNmMwk_89eQbk0rw94CzvLPQoY,907
|
3
|
+
invrs_opt/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
4
|
+
invrs_opt/experimental/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
5
|
+
invrs_opt/experimental/client.py,sha256=td5o_YqqbcSypDrWCVrHGSoF8UxEdOLtKU0z9Dth9lA,4842
|
6
|
+
invrs_opt/experimental/labels.py,sha256=dQDAMPyFMV6mXnMy295z8Ap205DRdVzysXny_Be8FmY,562
|
7
|
+
invrs_opt/lbfgsb/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
8
|
+
invrs_opt/lbfgsb/lbfgsb.py,sha256=59OpEYmGH3ofDv6m8KQQob5mQJei2vTcm1COh7SAbgA,27896
|
9
|
+
invrs_opt/lbfgsb/transform.py,sha256=a_Saj9Wq4lvqCJBrg5L2Z9DZ2NVs1xqrHLqha90a9Ws,5971
|
10
|
+
invrs_opt-0.5.0.dist-info/LICENSE,sha256=ty6jHPvpyjHy6dbhnu6aDSY05bbl2jQTjnq9u1sBCfM,1078
|
11
|
+
invrs_opt-0.5.0.dist-info/METADATA,sha256=kV8T1uAmMnr0IDaNjq1SK8btKa_XlyHjapKOfti_MbY,3326
|
12
|
+
invrs_opt-0.5.0.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
13
|
+
invrs_opt-0.5.0.dist-info/top_level.txt,sha256=hOziS2uJ_NgwaW9yhtOfeuYnm1X7vobPBcp_6eVWKfM,10
|
14
|
+
invrs_opt-0.5.0.dist-info/RECORD,,
|
invrs_opt-0.3.2.dist-info/RECORD
DELETED
@@ -1,11 +0,0 @@
|
|
1
|
-
invrs_opt/__init__.py,sha256=JG9h93Vq0AA2jX6zcqwxjA-LXOws8CJQeEbY9VQvQWQ,309
|
2
|
-
invrs_opt/base.py,sha256=dSX9QkMPzI8ROxy2cFNmMwk_89eQbk0rw94CzvLPQoY,907
|
3
|
-
invrs_opt/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
4
|
-
invrs_opt/lbfgsb/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
5
|
-
invrs_opt/lbfgsb/lbfgsb.py,sha256=2X0GVQwMCj2beYHLiAdwoAnBIdJLPThH0Jjduz3GzHA,25080
|
6
|
-
invrs_opt/lbfgsb/transform.py,sha256=a_Saj9Wq4lvqCJBrg5L2Z9DZ2NVs1xqrHLqha90a9Ws,5971
|
7
|
-
invrs_opt-0.3.2.dist-info/LICENSE,sha256=ty6jHPvpyjHy6dbhnu6aDSY05bbl2jQTjnq9u1sBCfM,1078
|
8
|
-
invrs_opt-0.3.2.dist-info/METADATA,sha256=pwrRENMlb_s1bNAeROw-cJ-nIVuqR9815r-jPNM3cEg,3272
|
9
|
-
invrs_opt-0.3.2.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
|
10
|
-
invrs_opt-0.3.2.dist-info/top_level.txt,sha256=hOziS2uJ_NgwaW9yhtOfeuYnm1X7vobPBcp_6eVWKfM,10
|
11
|
-
invrs_opt-0.3.2.dist-info/RECORD,,
|
File without changes
|
File without changes
|