fix(transform): search transformed int dims continuously, repair in natural space#88
Merged
Merged
Conversation
…atural space Closes #87. An integer dimension with an active transform was int-cast in TRANSFORMED space: (10, 5000, "log10") became internal bounds (1, 3), so internal rounding collapsed the dimension to the decade exponents {10, 100, 1000} in natural scale — and proposals drawn from the un-cast lower/upper arrays (1.0, 3.699) could round to exponent 4, i.e. 10000, silently EXCEEDING the declared cap (observed in a live spotforecast2 tuning run on 2026-06-05). The sqrt analogue restricted int dims to perfect squares. The integer constraint belongs to the natural scale, not the transformed scale: - transform_bounds keeps float internal bounds for int dims with an active transform (untransformed int and factor dims unchanged). - New SpotOptim.internal_var_type property: per-dimension types for internal-space repair — "float" for transformed int dims. All internal-space repair sites (initial design, user X0, design top-up, acquisition candidates/fallbacks) now use it. - New SpotOptim.repair_natural_X / utils.variables.repair_natural_X: rounds int dims to the nearest integer in NATURAL space and clips transformed ones to the declared bounds; applied in evaluate_function (the objective only ever sees admissible integers) and in the X_ / best_x_ storage paths (serial, restart, and steady-state parallel), so the recorded history matches what the objective saw. Handles full- and reduced-dimension layouts. - SpotOptimProtocol extended with the new members. - tests/test_int_log10_dims.py: 13 regression tests (continuous internal bounds, integer admissible values, no decade collapse, bound respect in history/best across serial and parallel paths, float+log10 and plain int dims unchanged). test_transform_bounds_mixed_var_types updated: it asserted the buggy int-cast; a new companion test pins the unchanged behaviour for untransformed int dims. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #87.
Problem
An integer dimension with an active transform was int-cast in transformed space:
(10, 5000, "log10")became internal bounds(1, 3), so internal rounding collapsed the dimension to decade exponents in natural scale — and proposals drawn from the un-castlower/upperfloat arrays(1.0, 3.699)could round to exponent 4, i.e. 10000, silently exceeding the declared cap of 5000 (observed in a live spotforecast2 tuning run on 2026-06-05). Thesqrtanalogue restricted int dims to perfect squares.Fix
The integer constraint belongs to the natural scale, not the transformed scale:
transform_boundskeeps float internal bounds for int dims with an active transform (untransformed int and factor dims unchanged — pinned by a new companion test).SpotOptim.internal_var_typeproperty; all internal-space repair sites (initial design, user X0, design top-up, acquisition candidates/fallbacks) use it, so transformed int dims are searched continuously.SpotOptim.repair_natural_X(+utils.variables.repair_natural_X): rounds int dims in natural space and clips transformed ones to the declared bounds; applied inevaluate_function(the objective only ever sees admissible integers) and in theX_/best_x_storage paths (serial, restart, steady-state parallel), so recorded history matches what the objective saw. Handles full- and reduced-dimension layouts.SpotOptimProtocolextended;docs/spotoptim_class.qmdmember list updated.Tests
tests/test_int_log10_dims.py— 13 regression tests: continuous internal bounds, integer admissible values within[10, 5000](never 10000), no decade collapse, bound respect inX_/best_x_across serial andn_jobs=2, float+log10 unchanged, plain int dims unchanged,repair_natural_Xunit behaviour.test_transform_bounds_mixed_var_typesupdated — it asserted the buggy int-cast.Verification
-m "not slow" -n auto): 1633 passedruff check src/ tests/clean; black/isort applied to changed files{python}examples execute🤖 Generated with Claude Code