roundSeqPreservingSum¶
- maelzel.distribute.roundSeqPreservingSum(seq, maxdelta=1, maxsolutions=1, ensureDirection=True)[source]¶
Round sequence preserving its integer sum
Find for each element in seq. an integer within the range x-maxdelta : x+maxdelta so that the sum of these integers is the same as the rounded sum of seq.
Note
This function is implemented using contraint programming. The search space grows very quickly as the seq grows so it can take a long time for large sequences.
- Parameters:
seq (
list
[float
]) – a list of numbersmaxdelta – the max. deviation the integer can have from the original item
maxsolutions – the max. number of solutions to generate before finding the best from those solutions. All solutions generated comply with the constraints given; the returned solutions as the one which follows the original seq. as closest
ensureDirection – if True, ensure that for any two numbers a and b, if a < b then a_rounded <= b_rounded (and similarly if a > b)
- Return type:
list
[int
]- Returns:
a list of integers representing the original seq. If there are no solutions an empty list is returned
Example
>>> from maelzel import distribute >>> from emlib.iterlib import pairwise >>> import matplotlib.pyplot as plt >>> parts = distribute.partitionExpon(40, 5, exp=3) >>> parts array([ 6.0952381 , 6.19047619, 6.85714286, 8.66666667, 12.19047619]) >>> round(sum(parts)) 40 >>> intparts = distribute.roundSeqPreservingSum(parts, maxsolutions=10) >>> intparts, sum(intparts) [6, 6, 7, 8, 13], 40