diff --git a/pretab/core/adaptive.py b/pretab/core/adaptive.py index 3015715..7a388ec 100644 --- a/pretab/core/adaptive.py +++ b/pretab/core/adaptive.py @@ -88,9 +88,14 @@ def _resolve_output_bounds( label = floor_label if floor_label is not None else str(floor) if lo < floor: + # ``lo`` is ``output_dim`` on the non-adaptive branch and whenever no + # explicit ``min_output_dim`` was supplied, so naming the parameter + # unconditionally pointed users at a knob they had not set -- and one + # that is ignored when ``adaptive`` is False. + name = "min_output_dim" if self.adaptive and min_req is not None else "output_dim" raise InvalidParamError( - f"min_output_dim must be >= {label}, got {lo}.\n" - "Fix: raise min_output_dim to at least the family minimum." + f"{name} must be >= {label}, got {lo}.\n" + f"Fix: raise {name} to at least the family minimum." ) if ceil is not None and hi > ceil: raise InvalidParamError( diff --git a/tests/test_adaptive_resolution.py b/tests/test_adaptive_resolution.py index 7a5a10f..835974a 100644 --- a/tests/test_adaptive_resolution.py +++ b/tests/test_adaptive_resolution.py @@ -254,3 +254,43 @@ def test_preprocessor_adaptive_rbf_within_window(frame): out = pre.fit_transform(X, y, return_array=True) assert isinstance(out, np.ndarray) assert 2 * 3 <= out.shape[1] <= 2 * 9 + + +# --------------------------------------------------------------------------- # +# The floor error must name the parameter the caller actually set. +# +# ``lo`` is ``output_dim`` on the non-adaptive branch, but the message always +# said "min_output_dim" -- a knob the user had not touched, and one that is +# ignored entirely when ``adaptive`` is False. +# --------------------------------------------------------------------------- # +def test_floor_error_names_output_dim_when_not_adaptive(): + from pretab.core.exceptions import InvalidParamError + + rng = np.random.default_rng(0) + frame = pd.DataFrame({"a": rng.normal(size=50)}) + + with pytest.raises(InvalidParamError, match="output_dim must be >= 1, got 0"): + Preprocessor(numerical_method="ple", output_dim=0).fit(frame, rng.normal(size=50)) + + +def test_floor_error_does_not_mention_min_output_dim_when_not_adaptive(): + from pretab.core.exceptions import InvalidParamError + + rng = np.random.default_rng(0) + frame = pd.DataFrame({"a": rng.normal(size=50)}) + + with pytest.raises(InvalidParamError) as excinfo: + Preprocessor(numerical_method="ple", output_dim=0).fit(frame, rng.normal(size=50)) + + assert "min_output_dim" not in str(excinfo.value) + + +def test_floor_error_names_min_output_dim_when_it_was_set(): + from pretab.core.exceptions import InvalidParamError + from pretab.transformers import PLETransformer + + rng = np.random.default_rng(0) + X = rng.normal(size=(50, 1)) + + with pytest.raises(InvalidParamError, match="min_output_dim must be >= 1"): + PLETransformer(output_dim=5, adaptive=True, min_output_dim=0).fit(X, rng.normal(size=50))