Repository navigation
refactor(synthesis): replace n_orientation_samples with orientation_resolution - #45
Merged
Merged
Conversation
…esolution
n_orientation_samples never denoted a number of samples. It was folded
into a per-axis grid resolution through
per_axis = max(6, int(round(n_samples ** (1.0 / free))))
so the floor swallowed it: with four precision points every value from 6
to 216 produced an identical search. Measured on the README's points, 6,
12, 36 and 72 all took the same time and returned the same ten solutions.
orientation_resolution is that per-axis number directly, which makes the
cost model readable from the signature: the grid holds
orientation_resolution ** (n_points - 1) candidates. The default of 6
reproduces the old default exactly, and a value passed to the old
argument is translated through the old formula, so no result moves.
Verified identical on five point sets.
The old name stays, warns, and is scheduled for removal in 2.0.0 under
the policy in docs/source/deprecations.md.
Two alternatives were implemented and rejected on measurement:
- Redefining the parameter as a total candidate budget, which its name
implies. On three of six point sets the search then returned nothing
where it had found ten.
- Reordering the grid coarse-to-fine, or shuffling it, in case a
truncated lexicographic product was merely sampling a biased corner.
Neither changed the solutions found nor the time taken, so candidates
are spread evenly through the grid and there is no cheaper subset.
The dense grid earns its cost. The search is unchanged; only the name was
wrong.
Also adds a warning when the grid exceeds a thousand candidates. Cost
grows exponentially in the number of precision points and nothing said
so: five points reach a four-dimensional grid that can run for seconds
and still return nothing.
Sibling functions keep n_orientation_samples, where it genuinely bounds
the number of orientations tried through their own loop counters. Their
calls into the generator are translated so their behaviour is unchanged.
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.
The last piece of #29, before 1.2.0.
The problem
n_orientation_samplesnever denoted a number of samples. It was folded into a per-axis grid resolution:With four precision points
free = 3, so every value from 6 to 216 givesper_axis = 6. Measured on the README's points,6,12,36and72all take the same time and return the same ten solutions.The replacement
The virtue is that the cost model becomes readable from the signature: the grid holds
orientation_resolution ** (n_points - 1)candidates. A user can see the exponential rather than discovering it at five points and nine seconds.The default of 6 reproduces the old default exactly. The old argument still works, warns, is translated through the old formula, and is scheduled for removal in 2.0.0 under the policy from #38. Verified identical on five point sets:
Two alternatives, implemented and rejected on measurement
A total candidate budget — what the name implies. Rejected: on three of six point sets the search returned nothing where it had found ten. Behaviour is a cliff, not a gradient, and the cliff sits somewhere problem-dependent that nobody can predict. A knob whose failure mode is silence is worse than a confusing one.
Coarse-to-fine or shuffled grid ordering — on the theory that truncating a lexicographic
product()samples a biased corner, so a budget might work if any prefix were representative. Measured across five point sets:Same solutions, differences within noise. Solutions are spread evenly through the grid rather than clustered, so there is no cheaper subset to find and no free speedup in the ordering. The dense grid earns its cost — the search is unchanged here, and only the name was ever wrong.
That finding is recorded as a comment in the generator, so the constant does not read as arbitrary and nobody repeats the experiment.
A warning where there was silence
Cost grows exponentially in the number of precision points, and nothing said so. Five points reach a four-dimensional grid that can run for seconds and return nothing. Calls whose grid exceeds a thousand candidates now warn up front, and the message is repeated in
SynthesisResult.warnings. Four points and fewer stay silent.Scope
Sibling functions (
six_bar_path_generation,generalized_synthesis,multi_topology.synthesize) keepn_orientation_samples, because there it is honest: they bound the number of orientations tried with their own loop counters, so the name matches the behaviour. Their calls into the generator go through an explicit_legacy_orientation_argstranslation, so their results are unchanged.Verification
tests/synthesis/test_orientation_resolution.py: the deprecation warns and names its replacement and removal release, the translation reproduces the old formula on five parameter/point combinations, the documented grid-size model is the real one, the candidate cap holds for six or more points, and the cost warning fires at five points but not at four or three.mypy --strictclean on 134 files. Docs build clean.One tidy-up carried along:
tests/synthesis/test_core_extended.pystill importedsynthesis.core.Dyad, so our own suite tripped the deprecation #38 introduced. It usesBurmesterDyadnow.