def get_sequence_period_of_rotation(sequence, n):
    '''Change `sequence` to period of rotation:

    ::

        >>> sequencetools.get_sequence_period_of_rotation([1, 2, 3, 1, 2, 3], 1)
        3

    ::

        >>> sequencetools.get_sequence_period_of_rotation([1, 2, 3, 1, 2, 3], 2)
        3

    ::

        >>> sequencetools.get_sequence_period_of_rotation([1, 2, 3, 1, 2, 3], 3)
        1

    Returns positive integer.
    '''

    degree = get_sequence_degree_of_rotational_symmetry(sequence)
    period = len(sequence) / degree
    divisors_of_n = set(mathtools.divisors(n))
    divisors_of_period = set(mathtools.divisors(period))
    max_shared_divisor = max(divisors_of_n & divisors_of_period)
    return period / max_shared_divisor
def test_mathtools_divisors_01():
    r'''Positive divisors of integer n.
    '''

    assert mathtools.divisors(1) == [1]
    assert mathtools.divisors(2) == [1, 2]
    assert mathtools.divisors(3) == [1, 3]
    assert mathtools.divisors(-4) == [1, 2, 4]
    assert mathtools.divisors(-5) == [1, 5]
    assert mathtools.divisors(-6) == [1, 2, 3, 6]
    assert mathtools.divisors(7) == [1, 7]
    assert mathtools.divisors(8) == [1, 2, 4, 8]
    assert mathtools.divisors(9) == [1, 3, 9]
    assert mathtools.divisors(10) == [1, 2, 5, 10]
Esempio n. 3
0
def test_mathtools_divisors_01():
    r'''Positive divisors of integer n.
    '''

    assert mathtools.divisors(1) == [1]
    assert mathtools.divisors(2) == [1, 2]
    assert mathtools.divisors(3) == [1, 3]
    assert mathtools.divisors(-4) == [1, 2, 4]
    assert mathtools.divisors(-5) == [1, 5]
    assert mathtools.divisors(-6) == [1, 2, 3, 6]
    assert mathtools.divisors(7) == [1, 7]
    assert mathtools.divisors(8) == [1, 2, 4, 8]
    assert mathtools.divisors(9) == [1, 3, 9]
    assert mathtools.divisors(10) == [1, 2, 5, 10]
Esempio n. 4
0
    def is_compound(self):
        r'''Is true when meter is compound. Otherwise false.

        ..  container:: example

            **Example 1.** Compound meters written over ``4``:

            ::

                >>> for numerator in range(1, 13):
                ...     meter = metertools.Meter((numerator, 4))
                ...     string = True if meter.is_compound else ''
                ...     print(str(meter), string)
                ...
                1/4 
                2/4 
                3/4 
                4/4 
                5/4 
                6/4     True
                7/4 
                8/4 
                9/4     True
                10/4 
                11/4 
                12/4    True

        ..  container:: example

            **Example 2.** Compound meters written over ``8``:

            ::

                >>> for numerator in range(1, 13):
                ...     meter = metertools.Meter((numerator, 8))
                ...     string = True if meter.is_compound else ''
                ...     print(str(meter), string)
                ...
                1/8 
                2/8 
                3/8 
                4/8 
                5/8 
                6/8     True
                7/8 
                8/8 
                9/8     True
                10/8 
                11/8 
                12/8    True

        Compound meters defined equal to those meters with a numerator
        divisible by ``3`` (but not equal to ``3``).

        Returns true or false.
        '''
        if 3 in mathtools.divisors(self.numerator):
            if not self.numerator == 3:
                return True
        return False
def greatest_common_divisor(*integers):
    '''Calculates greatest common divisor of `integers`.

    ::

        >>> mathtools.greatest_common_divisor(84, -94, -144)
        2

    Allows nonpositive input.

    Raises type error on noninteger input.

    Raises not implemented error when ``0`` is included in input.

    Returns positive integer.
    '''
    from abjad.tools import mathtools

    common_divisors = None
    for positive_integer in integers:
        all_divisors = set(mathtools.divisors(positive_integer))
        if common_divisors is None:
            common_divisors = all_divisors
        else:
            common_divisors &= all_divisors
            if common_divisors == set([1]):
                return 1
    return max(common_divisors)
Esempio n. 6
0
 def _is_valid_definition(self, definition):
     if not isinstance(definition, dict):
         return False
     elif 'divisors' not in definition:
         return False
     elif not len(definition['divisors']):
         return False
     elif not all(isinstance(x, int) and \
         1 < x for x in definition['divisors']):
         return False
     elif not all(mathtools.divisors(x) == [1, x] 
         for x in definition['divisors']):
         return False
     elif 'max_depth' not in definition:
         return False
     elif not isinstance(definition['max_depth'], int):
         return False
     elif not 0 < definition['max_depth']:
         return False
     elif 'max_divisions' not in definition:
         return False
     elif not isinstance(definition['max_divisions'], int):
         return False
     elif not 1 < definition['max_divisions']:
         return False
     return True
Esempio n. 7
0
    def is_compound(self):
        r'''Is true when meter is compound. Otherwise false.

        ..  container:: example

            **Example 1.** Compound meters written over ``4``:

            ::

                >>> for numerator in range(1, 13):
                ...     meter = metertools.Meter((numerator, 4))
                ...     string = True if meter.is_compound else ''
                ...     print(str(meter), string)
                ...
                1/4 
                2/4 
                3/4 
                4/4 
                5/4 
                6/4     True
                7/4 
                8/4 
                9/4     True
                10/4 
                11/4 
                12/4    True

        ..  container:: example

            **Example 2.** Compound meters written over ``8``:

            ::

                >>> for numerator in range(1, 13):
                ...     meter = metertools.Meter((numerator, 8))
                ...     string = True if meter.is_compound else ''
                ...     print(str(meter), string)
                ...
                1/8 
                2/8 
                3/8 
                4/8 
                5/8 
                6/8     True
                7/8 
                8/8 
                9/8     True
                10/8 
                11/8 
                12/8    True

        Compound meters defined equal to those meters with a numerator
        divisible by ``3`` (but not equal to ``3``).

        Returns true or false.
        '''
        if 3 in mathtools.divisors(self.numerator):
            if not self.numerator == 3:
                return True
        return False
Esempio n. 8
0
 def _is_valid_definition(self, definition):
     if not isinstance(definition, dict):
         return False
     elif 'divisors' not in definition:
         return False
     elif not len(definition['divisors']):
         return False
     elif not all(
             isinstance(x, int) and 1 < x for x in definition['divisors']):
         return False
     elif not all(
             mathtools.divisors(x) == [1, x]
             for x in definition['divisors']):
         return False
     elif 'max_depth' not in definition:
         return False
     elif not isinstance(definition['max_depth'], int):
         return False
     elif not 0 < definition['max_depth']:
         return False
     elif 'max_divisions' not in definition:
         return False
     elif not isinstance(definition['max_divisions'], int):
         return False
     elif not 1 < definition['max_divisions']:
         return False
     return True
Esempio n. 9
0
def greatest_common_divisor(*integers):
    '''Calculates greatest common divisor of `integers`.

    ..  container:: example

        >>> abjad.mathtools.greatest_common_divisor(84, -94, -144)
        2

    Allows nonpositive input.

    Raises not implemented error when zero is included in input.

    Returns positive integer.
    '''
    from abjad.tools import mathtools
    common_divisors = None
    for positive_integer in integers:
        all_divisors = set(mathtools.divisors(positive_integer))
        if common_divisors is None:
            common_divisors = all_divisors
        else:
            common_divisors &= all_divisors
            if common_divisors == set([1]):
                return 1
    return max(common_divisors)
Esempio n. 10
0
 def recurse(n):
     results = []
     for key in n:
         if not isinstance(key, int) or \
             not 0 < key or \
             not mathtools.divisors(key) == [1, key]:
             results.append(False)
         elif not isinstance(n[key], (dict, type(None))):
             results.append(False)
         elif isinstance(n[key], dict) and not recurse(n[key]):
             results.append(False)
         else:
             results.append(True)
     return results
Esempio n. 11
0
 def recurse(n):
     results = []
     for key in n:
         if not isinstance(key, int) or \
             not 0 < key or \
             not mathtools.divisors(key) == [1, key]:
             results.append(False)
         elif not isinstance(n[key], (dict, type(None))):
             results.append(False)
         elif isinstance(n[key], dict) and not recurse(n[key]):
             results.append(False)
         else:
             results.append(True)
     return results
Esempio n. 12
0
def rewrite_integer_tempo(integer_tempo, maximum_numerator=None, maximum_denominator=None):
    r'''Rewrite `integer_tempo`.

    Allow no tempo less than half `integer_tempo` or greater than double `integer_tempo`:

    ::

        >>> pairs = tempotools.rewrite_integer_tempo(
        ...     58, maximum_numerator=8, maximum_denominator=8)

    ::

        >>> for pair in pairs:
        ...     pair
        ...
        (Multiplier(1, 2), 29)
        (Multiplier(1, 1), 58)
        (Multiplier(3, 2), 87)
        (Multiplier(2, 1), 116)

    Returns list.
    '''

    # find divisors
    divisors = mathtools.divisors(integer_tempo)
    if maximum_denominator is not None:
      divisors = [x for x in divisors if x <= maximum_denominator]

    # make pairs
    pairs = []
    for divisor in divisors:
      start = int(math.ceil(divisor / 2.0))
      stop = 2 * divisor
      numerators = range(start, stop + 1)
      if maximum_numerator is not None:
            numerators = [x for x in numerators if x <= maximum_numerator]
      for numerator in numerators:
            multiplier = durationtools.Multiplier(numerator, divisor)
            new_tempo = fractions.Fraction(multiplier * integer_tempo)
            assert mathtools.is_integer_equivalent_number(new_tempo)
            new_tempo = int(new_tempo)
            pair = (multiplier, new_tempo)
            if pair not in pairs:
                pairs.append(pair)

    # sort pairs
    pairs.sort()

    # return pairs
    return pairs
Esempio n. 13
0
    def respell_division(self, division):
        r'''Respells `division` according to partition table.

        ..  container:: example

            **Example 1.** Respells divisions according to table:

            ::

                >>> table = rhythmmakertools.PartitionTable([
                ...     (2, [1, 1]),
                ...     (3, [2, 1]),
                ...     (5, [3, 2]),
                ...     (7, [4, 3]),
                ...     ])

            ::

                >>> for numerator in range(1, 15):
                ...     division = mathtools.NonreducedFraction(numerator, 4)
                ...     result = table.respell_division(division)
                ...     print((division, result))
                (NonreducedFraction(1, 4), [NonreducedFraction(1, 4)])
                (NonreducedFraction(2, 4), [NonreducedFraction(1, 4), NonreducedFraction(1, 4)])
                (NonreducedFraction(3, 4), [NonreducedFraction(2, 4), NonreducedFraction(1, 4)])
                (NonreducedFraction(4, 4), [NonreducedFraction(2, 4), NonreducedFraction(2, 4)])
                (NonreducedFraction(5, 4), [NonreducedFraction(3, 4), NonreducedFraction(2, 4)])
                (NonreducedFraction(6, 4), [NonreducedFraction(4, 4), NonreducedFraction(2, 4)])
                (NonreducedFraction(7, 4), [NonreducedFraction(4, 4), NonreducedFraction(3, 4)])
                (NonreducedFraction(8, 4), [NonreducedFraction(4, 4), NonreducedFraction(4, 4)])
                (NonreducedFraction(9, 4), [NonreducedFraction(6, 4), NonreducedFraction(3, 4)])
                (NonreducedFraction(10, 4), [NonreducedFraction(6, 4), NonreducedFraction(4, 4)])
                (NonreducedFraction(11, 4), [NonreducedFraction(11, 4)])
                (NonreducedFraction(12, 4), [NonreducedFraction(8, 4), NonreducedFraction(4, 4)])
                (NonreducedFraction(13, 4), [NonreducedFraction(13, 4)])
                (NonreducedFraction(14, 4), [NonreducedFraction(8, 4), NonreducedFraction(6, 4)])

        ..  container:: example

            **Example 2.** Respells divisions according to another table:

            ::

                >>> table = rhythmmakertools.PartitionTable([
                ...     (5, [1, 3, 1]),
                ...     (7, [1, 2, 4]),
                ...     ])

            ::

                >>> for numerator in range(1, 15):
                ...     division = mathtools.NonreducedFraction(numerator, 4)
                ...     result = table.respell_division(division)
                ...     print((division, result))
                (NonreducedFraction(1, 4), [NonreducedFraction(1, 4)])
                (NonreducedFraction(2, 4), [NonreducedFraction(2, 4)])
                (NonreducedFraction(3, 4), [NonreducedFraction(3, 4)])
                (NonreducedFraction(4, 4), [NonreducedFraction(4, 4)])
                (NonreducedFraction(5, 4), [NonreducedFraction(1, 4), NonreducedFraction(3, 4), NonreducedFraction(1, 4)])
                (NonreducedFraction(6, 4), [NonreducedFraction(6, 4)])
                (NonreducedFraction(7, 4), [NonreducedFraction(1, 4), NonreducedFraction(2, 4), NonreducedFraction(4, 4)])
                (NonreducedFraction(8, 4), [NonreducedFraction(8, 4)])
                (NonreducedFraction(9, 4), [NonreducedFraction(9, 4)])
                (NonreducedFraction(10, 4), [NonreducedFraction(2, 4), NonreducedFraction(6, 4), NonreducedFraction(2, 4)])
                (NonreducedFraction(11, 4), [NonreducedFraction(11, 4)])
                (NonreducedFraction(12, 4), [NonreducedFraction(12, 4)])
                (NonreducedFraction(13, 4), [NonreducedFraction(13, 4)])
                (NonreducedFraction(14, 4), [NonreducedFraction(2, 4), NonreducedFraction(4, 4), NonreducedFraction(8, 4)])

        Returns list of new divisions.
        '''
        division = mathtools.NonreducedFraction(division)
        result = [division]
        divisors = mathtools.divisors(division.numerator)
        for numerator, ratio in reversed(list(self.items())):
            if numerator in divisors:
                result = [division * _ for _ in ratio.multipliers]
                break
        result = [mathtools.NonreducedFraction(_) for _ in result]
        return result
Esempio n. 14
0
    def list_related_tempos(
        self, 
        maximum_numerator=None, 
        maximum_denominator=None,
        ):
        r'''Lists tempos related to this tempo.

        Returns list of tempo / ratio pairs.

        Each new tempo equals not less than half of this tempo
        and not more than twice this tempo.

        ..  container:: example

            Rewrites tempo ``58`` MM by ratios of the form ``n:d`` such that 
            ``1 <= n <= 8`` and ``1 <= d <= 8``:
            ...

            ::

                >>> tempo = Tempo(Duration(1, 4), 58)
                >>> pairs = tempo.list_related_tempos(
                ...     maximum_numerator=8, 
                ...     maximum_denominator=8,
                ...     )

            ::

                >>> for tempo, ratio in pairs:
                ...     string = '{!s}\t{!s}'.format(tempo, ratio)
                ...     print string
                4=29    1:2
                4=58    1:1
                4=87    3:2
                4=116   2:1

        ..  container:: example

            Rewrites tempo ``58`` MM by ratios of the form ``n:d`` such that
            ``1 <= n <= 30`` and ``1 <= d <= 30``:

            ::

                >>> tempo = Tempo(Duration(1, 4), 58)
                >>> pairs = tempo.list_related_tempos(
                ...     maximum_numerator=30, 
                ...     maximum_denominator=30,
                ...     )

            ::

                >>> for tempo, ratio in pairs:
                ...     string = '{!s}\t{!s}'.format(tempo, ratio)
                ...     print string
                ...
                4=30    15:29
                4=32    16:29
                4=34    17:29
                4=36    18:29
                4=38    19:29
                4=40    20:29
                4=42    21:29
                4=44    22:29
                4=46    23:29
                4=48    24:29
                4=50    25:29
                4=52    26:29
                4=54    27:29
                4=56    28:29
                4=58    1:1
                4=60    30:29

        Returns list.
        '''
        # assert integer tempo
        assert isinstance(self.units_per_minute, int), repr(self)
        # find divisors
        divisors = mathtools.divisors(self.units_per_minute)
        if maximum_denominator is not None:
            divisors = [x for x in divisors if x <= maximum_denominator]
        # make pairs
        pairs = []
        for divisor in divisors:
            start = int(math.ceil(divisor / 2.0))
            stop = 2 * divisor
            numerators = range(start, stop + 1)
            if maximum_numerator is not None:
                    numerators = [
                        x for x in numerators 
                        if x <= maximum_numerator
                        ]
        for numerator in numerators:
                ratio = mathtools.Ratio(numerator, divisor)
                multiplier = durationtools.Multiplier(*ratio)
                new_units_per_minute = multiplier * self.units_per_minute
                assert mathtools.is_integer_equivalent_expr(
                    new_units_per_minute)
                new_units_per_minute = int(new_units_per_minute)
                new_tempo = type(self)(self.duration, new_units_per_minute)
                pair = (new_tempo, ratio)
                if pair not in pairs:
                    pairs.append(pair)
        # sort pairs
        pairs.sort()
        # return pairs
        return pairs
Esempio n. 15
0
    def list_related_tempos(
        self,
        maximum_numerator=None,
        maximum_denominator=None,
        ):
        r'''Lists tempos related to this tempo.

        Returns list of tempo / ratio pairs.

        Each new tempo equals not less than half of this tempo
        and not more than twice this tempo.

        ..  container:: example

            Rewrites tempo ``58`` MM by ratios of the form ``n:d`` such that
            ``1 <= n <= 8`` and ``1 <= d <= 8``:
            ...

            ::

                >>> tempo = Tempo(Duration(1, 4), 58)
                >>> pairs = tempo.list_related_tempos(
                ...     maximum_numerator=8,
                ...     maximum_denominator=8,
                ...     )

            ::

                >>> for tempo, ratio in pairs:
                ...     string = '{!s}\t{!s}'.format(tempo, ratio)
                ...     print(string)
                4=29    1:2
                4=58    1:1
                4=87    3:2
                4=116   2:1

        ..  container:: example

            Rewrites tempo ``58`` MM by ratios of the form ``n:d`` such that
            ``1 <= n <= 30`` and ``1 <= d <= 30``:

            ::

                >>> tempo = Tempo(Duration(1, 4), 58)
                >>> pairs = tempo.list_related_tempos(
                ...     maximum_numerator=30,
                ...     maximum_denominator=30,
                ...     )

            ::

                >>> for tempo, ratio in pairs:
                ...     string = '{!s}\t{!s}'.format(tempo, ratio)
                ...     print(string)
                ... 
                4=30    15:29
                4=32    16:29
                4=34    17:29
                4=36    18:29
                4=38    19:29
                4=40    20:29
                4=42    21:29
                4=44    22:29
                4=46    23:29
                4=48    24:29
                4=50    25:29
                4=52    26:29
                4=54    27:29
                4=56    28:29
                4=58    1:1
                4=60    30:29

        Returns list.
        '''
        # assert integer tempo
        assert isinstance(self.units_per_minute, int), repr(self)
        # find divisors
        divisors = mathtools.divisors(self.units_per_minute)
        if maximum_denominator is not None:
            divisors = [x for x in divisors if x <= maximum_denominator]
        # make pairs
        pairs = []
        for divisor in divisors:
            start = int(math.ceil(divisor / 2.0))
            stop = 2 * divisor
            numerators = range(start, stop + 1)
            if maximum_numerator is not None:
                    numerators = [
                        x for x in numerators
                        if x <= maximum_numerator
                        ]
        for numerator in numerators:
                ratio = mathtools.Ratio(numerator, divisor)
                multiplier = durationtools.Multiplier(*ratio)
                new_units_per_minute = multiplier * self.units_per_minute
                assert mathtools.is_integer_equivalent_expr(
                    new_units_per_minute)
                new_units_per_minute = int(new_units_per_minute)
                new_tempo = type(self)(
                    duration=self.duration, 
                    units_per_minute=new_units_per_minute,
                    )
                pair = (new_tempo, ratio)
                if pair not in pairs:
                    pairs.append(pair)
        # sort pairs
        pairs.sort()
        # return pairs
        return pairs