[varLib.models] Add interpolateFromMastersAndMasterScalars()

Faster than the alternative way to calculate them.
This commit is contained in:
Behdad Esfahbod 2023-12-10 17:15:42 -07:00
parent c89971f662
commit 5a5898c824
2 changed files with 23 additions and 5 deletions

View File

@ -474,7 +474,7 @@ class VariationModel(object):
"""Return scalars for each delta, for the given location.
If interpolating many master-values at the same location,
this function allows speed up by fetching the scalars once
and using them with interpolateFromMastersAndScalars()"""
and using them with interpolateFromMastersAndScalars()."""
return [
supportScalar(
loc, support, extrapolate=self.extrapolate, axisRanges=self.axisRanges
@ -485,7 +485,8 @@ class VariationModel(object):
def getMasterScalars(self, targetLocation):
"""Return multipliers for each master, for the given location.
If interpolating many master-values at the same location,
this function allows speed up by fetching the scalars once.
this function allows speed up by fetching the scalars once
and using them with interpolateFromMastersAndMasterScalars().
Note that the scalars used in interpolateFromMastersAndScalars(),
are *not* the same as the ones returned here. They are the result
@ -530,6 +531,22 @@ class VariationModel(object):
deltas = self.getDeltas(masterValues, round=round)
return self.interpolateFromDeltasAndScalars(deltas, scalars)
@staticmethod
def interpolateFromMastersAndMasterScalars(masterValues, masterScalars):
"""Interpolate from master-values and master-scalars fetched
from getMasterScalars()."""
v = None
assert len(masterValues) == len(masterScalars)
for master, scalar in zip(masterValues, masterScalars):
if not scalar:
continue
contribution = master * scalar
if v is None:
v = contribution
else:
v += contribution
return v
def piecewiseLinearMap(v, mapping):
keys = mapping.keys()

View File

@ -452,9 +452,10 @@ class VariationModelTest(object):
assert interpolatedValue == expectedValue
assert masterScalars == model.getMasterScalars(instanceLocation)
assert (
sum(v * s for v, s in zip(masterValues, masterScalars)) == interpolatedValue
)
assert model.interpolateFromMastersAndMasterScalars(
masterValues, masterScalars
) == pytest.approx(interpolatedValue)
@pytest.mark.parametrize(
"masterLocations, location, expected",