From 865d6ee439d41a31028df7d9e8e44fd4061f259a Mon Sep 17 00:00:00 2001 From: Jonathan Wurth Date: Wed, 11 Dec 2024 21:22:46 +0100 Subject: [PATCH] Fix conversion of conditional parameters --- examples/multi_irace.py | 4 ++-- irace/_rpy2.py | 16 +++++++--------- irace/base.py | 2 +- 3 files changed, 10 insertions(+), 12 deletions(-) diff --git a/examples/multi_irace.py b/examples/multi_irace.py index a9673e4..c208b34 100644 --- a/examples/multi_irace.py +++ b/examples/multi_irace.py @@ -79,8 +79,8 @@ def target_runner2(experiment: Experiment, scenario: Scenario) -> float: ) if __name__ == '__main__': - run1 = Run(target_runner1, scenario, parameter_space1, name='dual_annealing') - run2 = Run(target_runner2, scenario, parameter_space2, name='differential_evolution') + run1 = Run(target_runner1, parameter_space1, scenario, name='dual_annealing') + run2 = Run(target_runner2, parameter_space2, scenario, name='differential_evolution') results = multi_irace([run1, run2], return_named=True, return_df=True, n_jobs=2, global_seed=42) diff --git a/irace/_rpy2.py b/irace/_rpy2.py index af78acb..2996064 100644 --- a/irace/_rpy2.py +++ b/irace/_rpy2.py @@ -32,15 +32,13 @@ converter = robjects.default_converter + robjects.numpy2ri.converter + robjects.pandas2ri.converter + def rpy2py_recursive(data: Any) -> Any: """ Step through an R object recursively and convert the types to python types as appropriate. Leaves will be converted to e.g. numpy arrays or lists as appropriate and the whole tree to a dictionary. """ - - if data in ( - rinterface.NULL, rinterface.NA_Character, rinterface.NA_Real, rinterface.NA_Integer, - rinterface.NA_Logical, rinterface.NA): + if data in (rinterface.NULL, rinterface.NA) or isinstance(data, (rinterface_lib.sexp.NACharacterType,)): return None elif type(data) in [robjects.DataFrame, robjects.ListVector]: return OrderedDict(zip(data.names, [rpy2py_recursive(elt) for elt in data])) @@ -53,7 +51,7 @@ def rpy2py_recursive(data: Any) -> Any: if len(data) == 1: return rpy2py_recursive(data[0]) else: - return np.array(data) + return np.array([rpy2py_recursive(d) for d in data]) else: if hasattr(data, "rclass"): # An unsupported r class raise KeyError(f"conversion for `{type(data)}` is not defined") @@ -78,12 +76,12 @@ def convert_configuration(raw_configuration: dict[str, Any], parameter_space: Pa continue if isinstance(subspace, p.Real): - param = float(raw_param) + param = float(raw_param) if not isinstance(raw_param, rinterface_lib.sexp.NARealType) else None elif isinstance(subspace, p.Integer): - param = int(raw_param) + param = int(raw_param) if not isinstance(raw_param, rinterface_lib.sexp.NAIntegerType) else None elif isinstance(subspace, p.Bool): # `bool` is represented as discrete with `["TRUE", "FALSE"]` variants. - param = bool(raw_param) + param = bool(raw_param) if not isinstance(raw_param, rinterface_lib.sexp.NACharacterType) else None elif isinstance(subspace, p.Categorical) or isinstance(subspace, p.Ordinal): # categorical and ordinal are represented as integers, so we need to convert to the real variant. param = subspace.values[int(raw_param)] @@ -157,7 +155,7 @@ def py2rpy_parameter_space(parameter_space: ParameterSpace) -> ListVector: transf = "log" if subspace.log else "" r_subspace = constructor(name=subspace.name, lower=lower, upper=upper, condition=condition, transf=transf) elif isinstance(subspace, p.Bool): - # `bool` is represented as discrete with `["0", "1"]` variants. + # `bool` is represented as discrete with `["FALSE", "TRUE"]` variants. values = BoolVector([False, True]) r_subspace = _irace.param_cat(subspace.name, values=values, condition=condition) elif isinstance(subspace, p.Categorical) or isinstance(subspace, p.Ordinal): diff --git a/irace/base.py b/irace/base.py index 46d22ac..3450149 100644 --- a/irace/base.py +++ b/irace/base.py @@ -44,7 +44,7 @@ def multi_irace(runs: Iterable[Run], n_jobs: int = 1, return_df: bool = False, r @delayed def inner(run: Run) -> pd.DataFrame | list[dict[str, Any]]: - return irace(target_runner=run.target_runner, scenario=run.scenario, + return irace(target_runner=run.target_runner, scenario=run.scenario, parameter_space=run.parameter_space, return_df=return_df, remove_metadata=remove_metadata) results = Parallel(n_jobs=n_jobs)(inner(run) for run in runs)