def test_mathtools_partition_integer_by_ratio_02(): r'''Partition integer n according to ratio. ''' partition = mathtools.partition_integer_by_ratio(10, [1, 2]) assert partition == [3, 7] partition = mathtools.partition_integer_by_ratio(10, [3, 1]) assert partition == [8, 2] partition = mathtools.partition_integer_by_ratio(-10, [-3, 2]) assert partition == [6, -4]
def partition_sequence_by_ratio_of_lengths(sequence, lengths): '''Partitions `sequence` by ratio of `lengths`. :: >>> sequence = tuple(range(10)) :: >>> sequencetools.partition_sequence_by_ratio_of_lengths( ... sequence, ... [1, 1, 2], ... ) [(0, 1, 2), (3, 4), (5, 6, 7, 8, 9)] Uses rounding magic to avoid fractional part lengths. Returns list of `sequence` objects. ''' from abjad.tools import sequencetools lengths = mathtools.partition_integer_by_ratio(len(sequence), lengths) return sequencetools.partition_sequence_by_counts( sequence, lengths, cyclic=False, overhang=False, )
def __call__(self, divisions=None): r'''Calls rounded ratio division maker on `division`. .. container:: example **Example 1.** Calls maker on nonempty input: :: >>> maker = makertools.SplitByRoundedRatiosDivisionCallback( ... ratios=[mathtools.Ratio([1, 1])], ... ) >>> lists = maker([(7, 4), (6, 4)]) >>> for list_ in lists: ... list_ [Division(4, 4), Division(3, 4)] [Division(3, 4), Division(3, 4)] Returns list of division lists. .. container:: example **Example 2.** Calls maker on empty input: :: >>> maker = makertools.SplitByRoundedRatiosDivisionCallback( ... ratios=[mathtools.Ratio([1, 1])], ... ) >>> maker([]) [] Returns empty list. Returns possibly empty list of division lists. ''' input_divisions = divisions or [] if not input_divisions: return [] output_division_lists = [] ratios = self._get_ratios() for i, input_division in enumerate(input_divisions): input_division = durationtools.Division(input_division) ratio = ratios[i] numerators = mathtools.partition_integer_by_ratio( input_division.numerator, ratio, ) output_division_list = [ durationtools.Division( numerator, input_division.denominator, ) for numerator in numerators ] output_division_lists.append(output_division_list) return output_division_lists
def test_mathtools_partition_integer_by_ratio_01(): r'''Partition integer n according to ratio. ''' t = mathtools.partition_integer_by_ratio(10, [1]) assert t == [10] t = mathtools.partition_integer_by_ratio(10, [1, 1]) assert t == [5, 5] t = mathtools.partition_integer_by_ratio(10, [1, -1, -1]) assert t == [3, -4, -3] t = mathtools.partition_integer_by_ratio(-10, [1, 1, 1, 1]) assert t == [-3, -2, -3, -2] t = mathtools.partition_integer_by_ratio(-10, [1, 1, 1, 1, 1]) assert t == [-2, -2, -2, -2, -2]
def __call__(self, divisions=None): r'''Calls rounded ratio division maker on `division`. .. container:: example **Example 1.** Calls maker on nonempty input: :: >>> maker = makertools.SplitByRoundedRatiosDivisionCallback( ... ratios=[mathtools.Ratio([1, 1])], ... ) >>> lists = maker([(7, 4), (6, 4)]) >>> for list_ in lists: ... list_ [NonreducedFraction(4, 4), NonreducedFraction(3, 4)] [NonreducedFraction(3, 4), NonreducedFraction(3, 4)] Returns list of division lists. .. container:: example **Example 2.** Calls maker on empty input: :: >>> maker = makertools.SplitByRoundedRatiosDivisionCallback( ... ratios=[mathtools.Ratio([1, 1])], ... ) >>> maker([]) [] Returns empty list. Returns possibly empty list of division lists. ''' input_divisions = divisions or [] if not input_divisions: return [] output_division_lists = [] ratios = self._get_ratios() for i, input_division in enumerate(input_divisions): input_division = mathtools.NonreducedFraction(input_division) ratio = ratios[i] numerators = mathtools.partition_integer_by_ratio( input_division.numerator, ratio, ) output_division_list = [ mathtools.NonreducedFraction( numerator, input_division.denominator, ) for numerator in numerators ] output_division_lists.append(output_division_list) return output_division_lists
def partition_sequence_by_ratio_of_lengths(sequence, ratio): '''Partitions `sequence` by `ratio` of lengths. .. container:: example **Example 1.** Partitions sequence by ``1:1:1`` ratio: :: >>> sequence = list(range(10)) >>> sequencetools.partition_sequence_by_ratio_of_lengths( ... sequence, ... [1, 1, 1], ... ) [[0, 1, 2], [3, 4, 5, 6], [7, 8, 9]] Returns list of lists. .. container:: example **Example 2.** Partitions sequence by ``1:1:2`` ratio: :: >>> sequence = tuple(range(10)) >>> sequencetools.partition_sequence_by_ratio_of_lengths( ... sequence, ... [1, 1, 2], ... ) [(0, 1, 2), (3, 4), (5, 6, 7, 8, 9)] Returns list of tuples. Uses the rounding magic implemented in ``mathtools.partition_integer_by_ratio()`` to avoid fractional part lengths. Returns list of `sequence` objects. ''' from abjad.tools import sequencetools if sequence is None: callback = sequencetools.PartitionByRatioOfLengthsCallback( ratio=ratio, ) return callback ratio = mathtools.Ratio(ratio) counts = mathtools.partition_integer_by_ratio(len(sequence), ratio) return sequencetools.partition_sequence_by_counts( sequence, counts, cyclic=False, overhang=Exact, )
def __call__(self, expr, rotation=None): r'''Calls ratio selector callback on `expr`. Returns tuple of selections. ''' assert isinstance(expr, tuple), repr(expr) assert len(expr) == 1, repr(expr) assert isinstance(expr[0], selectiontools.Selection), repr(expr) selection = expr[0] counts = mathtools.partition_integer_by_ratio( len(selection), self.ratio, ) selections = sequencetools.partition_sequence_by_counts( selection, counts=counts, ) return tuple(selections)
def drift(m, grid, n, mask): '''Creates subdivision grid under m; divides m leaves into n sections; subdivides sections in mask. For example: drift(m, [[0, 1, 2, 3], [0, 1], [0, 2, 3, 3]], 9, (1, 2, 6)) Divide the entire rhythmic voice m into 9 sections; then procede to subdivide only sections 1, 2 & 6 of those 9 sections; leave sections 3, 4, 5, 7, 8, 9 unsubidivide; when dividing elements in sections 1, 2 & 6, interpret the 0, 1, 2, 3 in mask in the following way: 0 -- do not subdivide; 1 -- create eighth notes; 2 -- create sixteenth notes; 3 -- create thirty-second notes. ''' grid = baca.tools.helianthate(grid, 1, 1) grid = sequencetools.repeat_to_length(grid, len(m.leaves)) #sections = baca.tools.ratio(len(m.instances('Leaf')), [1] * n) num_leaves = len(instances(m, '_Leaf')) sections = mathtools.partition_integer_by_ratio(num_leaves, [1] * n) pairs = sequencetools.list_pairwise_cumulative_sums_zero(sections) sections = [range(*pair) for pair in pairs] sections = reduce(operator.add, [sections[section - 1] for section in mask]) # 'sections' at this point is a flat zero-indexed list of elements in m # to subdivide; for example [0, 1, 2, 3, 4, 35, 36, 37, 38, 39, 118, ...] positions = [pair[-1] if pair[0] in sections else 0 for pair in enumerate(grid)] # 'positions' is a look-up table implemented as a flat list; # element 0 in 'positions' specifies how many times to subidivide 0 in m; # element 1 in 'positions' specifies how many times to subidivide 1 in m; # etc, ... sekka.etc.transforms.subdivide(m, positions) #baca.tools.abjad_subdivide(m, positions)
def make_territoires_parts(): ratio = [1] * 9 lengths = mathtools.partition_integer_by_ratio(164, ratio) parts = sequencetools.partition_by_lengths(fully_labelled_cells, lengths) parts = sequencetools.rotate(parts, -3) territoires_parts = parts[:2] + parts[3:8] originals = range(1, 9 + 1) ## territoires part numbers are [(4, 5), 6, (7, 8, 9, 1, 2), 3] territoires_part_numbers = [4, 5, 7, 8, 9, 1, 2] original_territoires_part_numbers = zip(originals, territoires_part_numbers) parts = sequencetools.rotate(parts, -3) manifolds_parts = parts[:4] + parts[5:] ## manifolds part numbers are [(7, 8, 9, 1), 2, (3, 4, 5, 6)] manifolds_part_numbers = [7, 8, 9, 1, 3, 4, 5, 6] original_manifolds_part_numbers = zip(originals, manifolds_part_numbers) return territoires_parts, original_territoires_part_numbers, \ manifolds_parts, original_manifolds_part_numbers
def partition_sequence_by_ratio_of_weights(sequence, weights): '''Partitions `sequence` by ratio of `weights`. :: >>> sequencetools.partition_sequence_by_ratio_of_weights( ... [1] * 10, [1, 1, 1]) [[1, 1, 1], [1, 1, 1, 1], [1, 1, 1]] :: >>> sequencetools.partition_sequence_by_ratio_of_weights( ... [1] * 10, [1, 1, 1, 1]) [[1, 1, 1], [1, 1], [1, 1, 1], [1, 1]] :: >>> sequencetools.partition_sequence_by_ratio_of_weights( ... [1] * 10, [2, 2, 3]) [[1, 1, 1], [1, 1, 1], [1, 1, 1, 1]] :: >>> sequencetools.partition_sequence_by_ratio_of_weights( ... [1] * 10, [3, 2, 2]) [[1, 1, 1, 1], [1, 1, 1], [1, 1, 1]] :: >>> sequencetools.partition_sequence_by_ratio_of_weights( ... [1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2], [1, 1]) [[1, 1, 1, 1, 1, 1, 2, 2], [2, 2, 2, 2]] :: >>> sequencetools.partition_sequence_by_ratio_of_weights( ... [1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2], [1, 1, 1]) [[1, 1, 1, 1, 1, 1], [2, 2, 2], [2, 2, 2]] Weights of parts of returned list equal `weights_ratio` proportions with some rounding magic. Returns list of lists. ''' from abjad.tools import sequencetools list_weight = mathtools.weight(sequence) weights_parts = mathtools.partition_integer_by_ratio(list_weight, weights) cumulative_weights = mathtools.cumulative_sums(weights_parts, start=None) result = [] sublist = [] result.append(sublist) current_cumulative_weight = cumulative_weights.pop(0) for n in sequence: if not isinstance(n, (int, long, float, fractions.Fraction)): message = 'must be number: {!r}.' message = message.format(n) raise TypeError(message) sublist.append(n) while current_cumulative_weight <= \ mathtools.weight(sequencetools.flatten_sequence(result)): try: current_cumulative_weight = cumulative_weights.pop(0) sublist = [] result.append(sublist) except IndexError: break return result
def __call__(self, divisions=None): r'''Calls rounded ratio division maker on `divisions`. .. container:: example **Example 1.** Calls maker on nonempty input: :: >>> maker = makertools.SplitByRoundedRatiosDivisionCallback( ... ratios=[mathtools.Ratio([1, 1])], ... ) >>> lists = maker([(7, 4), (6, 4)]) >>> for list_ in lists: ... list_ [Division((4, 4)), Division((3, 4))] [Division((3, 4)), Division((3, 4))] Returns list of division lists. .. container:: example **Example 2.** Calls maker on empty input: :: >>> maker = makertools.SplitByRoundedRatiosDivisionCallback( ... ratios=[mathtools.Ratio([1, 1])], ... ) >>> maker([]) [] Returns empty list. .. container:: example **Example 3.** Works with start offset: :: >>> maker = makertools.SplitByRoundedRatiosDivisionCallback( ... ratios=[mathtools.Ratio([1, 1])], ... ) :: >>> divisions = [(7, 4), (6, 4)] >>> divisions = [durationtools.Division(_) for _ in divisions] >>> divisions[0]._start_offset = Offset(1, 4) >>> divisions [Division((7, 4), start_offset=Offset(1, 4)), Division((6, 4))] :: >>> division_lists = maker(divisions) >>> len(division_lists) 2 :: >>> for division in division_lists[0]: ... division Division((4, 4), start_offset=Offset(1, 4)) Division((3, 4), start_offset=Offset(5, 4)) :: >>> for division in division_lists[1]: ... division Division((3, 4), start_offset=Offset(2, 1)) Division((3, 4), start_offset=Offset(11, 4)) Returns possibly empty list of division lists. ''' from experimental import makertools divisions = divisions or [] if not divisions: return [] divisions, start_offset = makertools.DivisionMaker._to_divisions( divisions) start_offset = divisions[0].start_offset division_lists = [] ratios = self._get_ratios() for i, division in enumerate(divisions): ratio = ratios[i] numerators = mathtools.partition_integer_by_ratio( division.numerator, ratio, ) division_list = [ durationtools.Division((numerator, division.denominator)) for numerator in numerators ] division_lists.append(division_list) division_lists, start_offset = makertools.DivisionMaker._to_divisions( division_lists, start_offset=start_offset, ) return division_lists
def partition_sequence_by_ratio_of_weights(sequence, weights): '''Partitions `sequence` by ratio of `weights`. :: >>> sequencetools.partition_sequence_by_ratio_of_weights( ... [1] * 10, [1, 1, 1]) [[1, 1, 1], [1, 1, 1, 1], [1, 1, 1]] :: >>> sequencetools.partition_sequence_by_ratio_of_weights( ... [1] * 10, [1, 1, 1, 1]) [[1, 1, 1], [1, 1], [1, 1, 1], [1, 1]] :: >>> sequencetools.partition_sequence_by_ratio_of_weights( ... [1] * 10, [2, 2, 3]) [[1, 1, 1], [1, 1, 1], [1, 1, 1, 1]] :: >>> sequencetools.partition_sequence_by_ratio_of_weights( ... [1] * 10, [3, 2, 2]) [[1, 1, 1, 1], [1, 1, 1], [1, 1, 1]] :: >>> sequencetools.partition_sequence_by_ratio_of_weights( ... [1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2], [1, 1]) [[1, 1, 1, 1, 1, 1, 2, 2], [2, 2, 2, 2]] :: >>> sequencetools.partition_sequence_by_ratio_of_weights( ... [1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2], [1, 1, 1]) [[1, 1, 1, 1, 1, 1], [2, 2, 2], [2, 2, 2]] Weights of parts of returned list equal `weights_ratio` proportions with some rounding magic. Returns list of lists. ''' from abjad.tools import sequencetools if not isinstance(sequence, collections.Sequence): message = 'must be sequence: {!r}.' message = message.format(sequence) raise Exception(message) list_weight = mathtools.weight(sequence) weights_parts = mathtools.partition_integer_by_ratio(list_weight, weights) cumulative_weights = mathtools.cumulative_sums(weights_parts, start=None) result = [] sublist = [] result.append(sublist) current_cumulative_weight = cumulative_weights.pop(0) for n in sequence: if not isinstance(n, (int, float, fractions.Fraction)): message = 'must be number: {!r}.' message = message.format(n) raise TypeError(message) sublist.append(n) while current_cumulative_weight <= \ mathtools.weight(sequencetools.flatten_sequence(result)): try: current_cumulative_weight = cumulative_weights.pop(0) sublist = [] result.append(sublist) except IndexError: break return result