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]
Esempio n. 2
0
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 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,
        )
Esempio n. 8
0
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)
Esempio n. 10
0
    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)
Esempio n. 11
0
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
Esempio n. 15
0
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