[instancer/L4] Implement an optimization
This commit is contained in:
parent
17761cc616
commit
10bc7a804a
@ -153,77 +153,104 @@ def _solve(tent, axisLimit, negative=False):
|
||||
out.append((scalar1 - gain, loc1))
|
||||
out.append((scalar2 - gain, loc2))
|
||||
|
||||
# Case 3: Outermost limit still fits within F2Dot14 bounds;
|
||||
# we keep deltas as is and only scale the axes bounds. Deltas beyond -1.0
|
||||
# or +1.0 will never be applied as implementations must clamp to that range.
|
||||
#
|
||||
# A second tent is needed for cases when gain is positive, though we add it
|
||||
# unconditionally and it will be dropped because scalar ends up 0.
|
||||
#
|
||||
# TODO: See if we can just move upper closer to adjust the slope, instead of
|
||||
# second tent.
|
||||
#
|
||||
# | peak |
|
||||
# 1.........|............o...|..................
|
||||
# | /x\ |
|
||||
# | /xxx\ |
|
||||
# | /xxxxx\|
|
||||
# | /xxxxxxx+
|
||||
# | /xxxxxxxx|\
|
||||
# 0---|-----|------oxxxxxxxxx|xo---------------1
|
||||
# axisMin | lower | upper
|
||||
# | |
|
||||
# axisDef axisMax
|
||||
#
|
||||
elif axisDef + (axisMax - axisDef) * 2 >= upper:
|
||||
if not negative and axisDef + (axisMax - axisDef) * MAX_F2DOT14 < upper:
|
||||
# we clamp +2.0 to the max F2Dot14 (~1.99994) for convenience
|
||||
upper = axisDef + (axisMax - axisDef) * MAX_F2DOT14
|
||||
assert peak < upper
|
||||
|
||||
else:
|
||||
# Special-case if peak is at axisMax.
|
||||
if axisMax == peak:
|
||||
upper = peak
|
||||
|
||||
loc1 = (max(axisDef, lower), peak, upper)
|
||||
scalar1 = 1
|
||||
# Case pre3:
|
||||
# we keep deltas as is and only scale the axis upper to achieve
|
||||
# the desired new tent if feasible.
|
||||
#
|
||||
# | peak |
|
||||
# 1.........|............o...|..................
|
||||
# | /x\ |
|
||||
# | /xxx\ |
|
||||
# | /xxxxx\|
|
||||
# | /xxxxxxx+
|
||||
# | /xxxxxxxx|\
|
||||
# 0---|-----|------oxxxxxxxxx|xo---------------1
|
||||
# axisMin | lower | upper
|
||||
# | |
|
||||
# axisDef axisMax
|
||||
#
|
||||
newUpper = peak + (1 - gain) * (upper - peak)
|
||||
if axisMax <= newUpper and newUpper <= axisDef + (axisMax - axisDef) * 2:
|
||||
upper = newUpper
|
||||
if not negative and axisDef + (axisMax - axisDef) * MAX_F2DOT14 < upper:
|
||||
# we clamp +2.0 to the max F2Dot14 (~1.99994) for convenience
|
||||
upper = axisDef + (axisMax - axisDef) * MAX_F2DOT14
|
||||
assert peak < upper
|
||||
|
||||
loc2 = (peak, upper, upper)
|
||||
scalar2 = 0
|
||||
loc = (max(axisDef, lower), peak, upper)
|
||||
scalar = 1
|
||||
|
||||
out.append((scalar - gain, loc))
|
||||
|
||||
# Case 3: Outermost limit still fits within F2Dot14 bounds;
|
||||
# We keep axis bound as is. Deltas beyond -1.0 or +1.0 will never be
|
||||
# applied as implementations must clamp to that range.
|
||||
#
|
||||
# A second tent is needed for cases when gain is positive, though we add it
|
||||
# unconditionally and it will be dropped because scalar ends up 0.
|
||||
#
|
||||
# | peak |
|
||||
# 1.........|............o...|..................
|
||||
# | /x\ |
|
||||
# | /xxx\ |
|
||||
# | /xxxxx\|
|
||||
# | /xxxxxxx+
|
||||
# | /xxxxxxxx|\
|
||||
# 0---|-----|------oxxxxxxxxx|xo---------------1
|
||||
# axisMin | lower | upper
|
||||
# | |
|
||||
# axisDef axisMax
|
||||
#
|
||||
elif axisDef + (axisMax - axisDef) * 2 >= upper:
|
||||
if not negative and axisDef + (axisMax - axisDef) * MAX_F2DOT14 < upper:
|
||||
# we clamp +2.0 to the max F2Dot14 (~1.99994) for convenience
|
||||
upper = axisDef + (axisMax - axisDef) * MAX_F2DOT14
|
||||
assert peak < upper
|
||||
|
||||
loc1 = (max(axisDef, lower), peak, upper)
|
||||
scalar1 = 1
|
||||
|
||||
loc2 = (peak, upper, upper)
|
||||
scalar2 = 0
|
||||
|
||||
# Don't add a dirac delta!
|
||||
if axisDef < upper:
|
||||
out.append((scalar1 - gain, loc1))
|
||||
if peak < upper:
|
||||
out.append((scalar2 - gain, loc2))
|
||||
|
||||
# Case 4: New limit doesn't fit; we need to chop into two tents,
|
||||
# because the shape of a triangle with part of one side cut off
|
||||
# cannot be represented as a triangle itself.
|
||||
#
|
||||
# | peak |
|
||||
# 1.........|......o.|....................
|
||||
# ..........|...../x\|.............outGain
|
||||
# | |xxy|\_
|
||||
# | /xxxy| \_
|
||||
# | |xxxxy| \_
|
||||
# | /xxxxy| \_
|
||||
# 0---|-----|-oxxxxxx| o----------1
|
||||
# axisMin | lower | upper
|
||||
# | |
|
||||
# axisDef axisMax
|
||||
#
|
||||
else:
|
||||
loc1 = (max(axisDef, lower), peak, axisMax)
|
||||
scalar1 = 1
|
||||
|
||||
loc2 = (peak, axisMax, axisMax)
|
||||
scalar2 = outGain
|
||||
|
||||
# Don't add a dirac delta!
|
||||
if axisDef < upper:
|
||||
out.append((scalar1 - gain, loc1))
|
||||
if peak < upper:
|
||||
out.append((scalar2 - gain, loc2))
|
||||
|
||||
# Case 4: New limit doesn't fit; we need to chop into two tents,
|
||||
# because the shape of a triangle with part of one side cut off
|
||||
# cannot be represented as a triangle itself.
|
||||
#
|
||||
# | peak |
|
||||
# 1.........|......o.|....................
|
||||
# ..........|...../x\|.............outGain
|
||||
# | |xxy|\_
|
||||
# | /xxxy| \_
|
||||
# | |xxxxy| \_
|
||||
# | /xxxxy| \_
|
||||
# 0---|-----|-oxxxxxx| o----------1
|
||||
# axisMin | lower | upper
|
||||
# | |
|
||||
# axisDef axisMax
|
||||
#
|
||||
else:
|
||||
loc1 = (max(axisDef, lower), peak, axisMax)
|
||||
scalar1 = 1
|
||||
|
||||
loc2 = (peak, axisMax, axisMax)
|
||||
scalar2 = outGain
|
||||
|
||||
out.append((scalar1 - gain, loc1))
|
||||
# Don't add a dirac delta!
|
||||
if peak < axisMax:
|
||||
out.append((scalar2 - gain, loc2))
|
||||
# Don't add a dirac delta!
|
||||
if peak < axisMax:
|
||||
out.append((scalar2 - gain, loc2))
|
||||
|
||||
# Now, the negative side
|
||||
|
||||
|
@ -137,8 +137,7 @@ class RebaseTentTest(object):
|
||||
(0.25, 0.25, 0.75),
|
||||
[
|
||||
(0.5, None),
|
||||
(0.5, (0, 0.5, 1.5)),
|
||||
(-0.5, (0.5, 1.5, 1.5)),
|
||||
(0.5, (0, 0.5, 1.0)),
|
||||
],
|
||||
),
|
||||
# Case 1neg
|
||||
|
Loading…
x
Reference in New Issue
Block a user