Skip to content

Commit 0ea8078

Browse files
FFroehlichdweindl
andauthored
Fides 0.7.3 (#48)
* Verify options are of correct type (#45) * Verify options are of correct type Wasn't checked so far and led to very uninformative errors if wrong options were passed. * Apply suggestions from code review Co-authored-by: Fabian Fröhlich <[email protected]> * fix runtime warning for unbouned vars, fixes #46 * fixup * fix refined step * move validation check, reenable passing strs for enums * fixup option validation, remove deprecated checks * Update version.py Co-authored-by: Daniel Weindl <[email protected]>
1 parent 4a666b5 commit 0ea8078

File tree

5 files changed

+66
-47
lines changed

5 files changed

+66
-47
lines changed

fides/constants.py

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,11 @@
88
import enum
99
import numpy as np
1010

11+
from numbers import Real, Integral
12+
from pathlib import PosixPath, WindowsPath
13+
14+
from typing import Dict
15+
1116

1217
class Options(str, enum.Enum):
1318
"""
@@ -91,3 +96,44 @@ class ExitFlag(int, enum.Enum):
9196
FTOL = 1 #: Converged according to fval difference
9297
XTOL = 2 #: Converged according to x difference
9398
GTOL = 3 #: Converged according to gradient norm
99+
100+
101+
def validate_options(options: Dict):
102+
"""Check if the chosen options are valid"""
103+
expected_types = {
104+
Options.MAXITER: Integral,
105+
Options.MAXTIME: Real,
106+
Options.FATOL: Real,
107+
Options.FRTOL: Real,
108+
Options.XTOL: Real,
109+
Options.GATOL: Real,
110+
Options.GRTOL: Real,
111+
Options.SUBSPACE_DIM: (SubSpaceDim, str),
112+
Options.STEPBACK_STRAT: (StepBackStrategy, str),
113+
Options.THETA_MAX: Real,
114+
Options.DELTA_INIT: Real,
115+
Options.MU: Real,
116+
Options.ETA: Real,
117+
Options.GAMMA1: Real,
118+
Options.GAMMA2: Real,
119+
Options.HISTORY_FILE: (str, PosixPath, WindowsPath),
120+
}
121+
for option_key, option_value in options.items():
122+
try:
123+
option = Options(option_key)
124+
except ValueError:
125+
raise ValueError(f'{option_key} is not a valid options field.')
126+
127+
if option_key is Options.SUBSPACE_DIM:
128+
option_value = SubSpaceDim(option_value)
129+
130+
if option_key is Options.STEPBACK_STRAT:
131+
option_value = StepBackStrategy(option_value)
132+
133+
expected_type = expected_types[option]
134+
if not isinstance(option_value, expected_type):
135+
if expected_type == Integral and int(option_value) == option_value:
136+
continue
137+
raise TypeError(f'Type mismatch for option {option_key}. '
138+
f'Expected {expected_type} but got '
139+
f'{type(option_value)}')

fides/minimize.py

Lines changed: 2 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,11 @@
1818
HybridFraction, FX, IterativeHessianApproximation, TSSM, GNSBFGS
1919
)
2020
from .constants import (
21-
Options, ExitFlag, DEFAULT_OPTIONS, StepBackStrategy, SubSpaceDim
21+
Options, ExitFlag, DEFAULT_OPTIONS, StepBackStrategy, SubSpaceDim,
22+
validate_options
2223
)
2324
from .logging import create_logger
2425
from collections import defaultdict
25-
from numbers import Real, Integral
26-
from pathlib import PosixPath, WindowsPath
2726
from typing import Callable, Dict, Optional, Tuple, Union, List
2827

2928

@@ -832,50 +831,9 @@ def check_in_bounds(self, x: Optional[np.ndarray] = None):
832831
f'{diff[ix]} {pointstr}')
833832

834833
def get_option(self, option):
835-
if option not in Options:
836-
raise ValueError(f'{option} is not a valid option name.')
837-
838-
if option not in DEFAULT_OPTIONS:
839-
raise ValueError(f'{option} is missing its default option.')
840-
841834
return self.options.get(option, DEFAULT_OPTIONS.get(option))
842835

843836

844837
def _min_max_evs(mat: np.ndarray):
845838
evs = np.linalg.eigvals(mat)
846839
return np.real(np.min(evs)), np.real(np.max(evs))
847-
848-
849-
def validate_options(options: Dict):
850-
"""Check if the chosen options are valid"""
851-
expected_types = {
852-
Options.MAXITER: Integral,
853-
Options.MAXTIME: Real,
854-
Options.FATOL: Real,
855-
Options.FRTOL: Real,
856-
Options.XTOL: Real,
857-
Options.GATOL: Real,
858-
Options.GRTOL: Real,
859-
Options.SUBSPACE_DIM: SubSpaceDim,
860-
Options.STEPBACK_STRAT: StepBackStrategy,
861-
Options.THETA_MAX: Real,
862-
Options.DELTA_INIT: Real,
863-
Options.MU: Real,
864-
Options.ETA: Real,
865-
Options.GAMMA1: Real,
866-
Options.GAMMA2: Real,
867-
Options.HISTORY_FILE: (str, PosixPath, WindowsPath),
868-
}
869-
for option_key, option_value in options.items():
870-
try:
871-
option = Options(option_key)
872-
except ValueError:
873-
raise ValueError(f'{option_key} is not a valid options field.')
874-
875-
expected_type = expected_types[option]
876-
if not isinstance(option_value, expected_type):
877-
if expected_type == Integral and int(option_value) == option_value:
878-
continue
879-
raise TypeError(f'Type mismatch for option {option_key}. '
880-
f'Expected {expected_type} but got '
881-
f'{type(option_value)}')

fides/trust_region.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,6 @@ def trust_region(x: np.ndarray,
7878
SubSpaceDim.FULL: TRStepFull,
7979
SubSpaceDim.STEIHAUG: TRStepSteihaug,
8080
}
81-
if subspace_dim not in step_options:
82-
raise ValueError('Invalid choice of subspace dimension.')
8381
tr_step = step_options[subspace_dim](x, sg, hess, scaling, g_dscaling,
8482
delta, theta, ub, lb, logger)
8583
tr_step.calculate()

fides/version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = "0.7.2"
1+
__version__ = "0.7.3"

tests/test_minimize.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -382,3 +382,20 @@ def test_wrong_options():
382382
fun, ub=ub, lb=lb, verbose=logging.INFO,
383383
options={Options.FATOL: 'not a number'}
384384
)
385+
386+
# check we can pass floats for ints
387+
Optimizer(
388+
fun, ub=ub, lb=lb, verbose=logging.INFO,
389+
options={Options.MAXITER: 1e4}
390+
)
391+
with pytest.raises(ValueError):
392+
Optimizer(
393+
fun, ub=ub, lb=lb, verbose=logging.INFO,
394+
options={Options.SUBSPACE_DIM: 'invalid_subspace'}
395+
)
396+
397+
# check we can pass strings for enums
398+
Optimizer(
399+
fun, ub=ub, lb=lb, verbose=logging.INFO,
400+
options={Options.SUBSPACE_DIM: '2D'}
401+
)

0 commit comments

Comments
 (0)