[instancer.solver] Handle when peak falls on new axis default

This commit is contained in:
Behdad Esfahbod 2022-08-09 20:25:31 -06:00
parent 528bcdf1a2
commit e08553011a
3 changed files with 33 additions and 5 deletions

View File

@ -255,9 +255,6 @@ def changeTupleVariationAxisLimit(var, axisTag, axisLimit):
if tent is None: if tent is None:
newVar.axes.pop(axisTag) newVar.axes.pop(axisTag)
else: else:
# Sometimes happens when can't be solved. Eg. if a dirac function
# (tent with upper==peak==lower) is placed at axisLimit's default
# location.
assert tent[1] != 0, tent assert tent[1] != 0, tent
newVar.axes[axisTag] = tent newVar.axes[axisTag] = tent
newVar.scaleDeltas(scalar) newVar.scaleDeltas(scalar)

View File

@ -252,7 +252,27 @@ def _solve(tent, axisLimit, negative=False):
out.append((scalar1 - gain, loc1)) out.append((scalar1 - gain, loc1))
out.append((scalar2 - gain, loc2)) out.append((scalar2 - gain, loc2))
return out
# If peak ended up being zero, nudge it to the next value
EPSILON = 1 / (1 << 14)
new_out = []
for scalar,triple in out:
if scalar == 0:
continue
if triple is None:
new_out.append((scalar, triple))
continue
lower,peak,upper = triple
if peak == axisDef:
assert not (lower == upper == axisDef)
peak += EPSILON if lower == axisDef else -EPSILON
new_out.append((scalar, (lower,peak,upper)))
return new_out
@lru_cache(128) @lru_cache(128)
@ -279,6 +299,6 @@ def rebaseTent(tent, axisLimit):
sols = _solve(tent, axisLimit) sols = _solve(tent, axisLimit)
n = lambda v: normalizeValue(v, axisLimit, extrapolate=True) n = lambda v: normalizeValue(v, axisLimit, extrapolate=True)
sols = [(scalar, (n(v[0]), n(v[1]), n(v[2])) if v is not None else None) for scalar,v in sols if scalar != 0] sols = [(scalar, (n(v[0]), n(v[1]), n(v[2])) if v is not None else None) for scalar,v in sols]
return sols return sols

View File

@ -213,6 +213,17 @@ class RebaseTentTest(object):
(1, (0, .4, 1.99994)), (1, (0, .4, 1.99994)),
] ]
), ),
# Dirac delta at new default. Fancy!
pytest.param(
(.5, .5, .5), (0, .5, 1),
[
(1, None),
(-1, (0, 0.0001220703, 1)),
(-1, (0, 1, 1)),
(-1, (-1, -0.0001220703, 0)),
(-1, (-1, -1, 0)),
]
),
], ],
) )
def test_rebaseTent(self, tent, axisRange, expected): def test_rebaseTent(self, tent, axisRange, expected):