示例#1
0
 def _from_number(self, argument):
     direction = mathtools.sign(argument)
     number = self._to_nearest_quarter_tone(abs(argument))
     pc_number = number % 12
     if pc_number == 0 and number:
         pc_number = 12
     self._number = pc_number * direction
示例#2
0
    def direction_number(self):
        """
        Gets direction number of named interval.

        ..  container:: example

            >>> abjad.NamedInterval('+M9').direction_number
            1

            >>> abjad.NamedInterval('+dim2').direction_number
            1

            >>> abjad.NamedInterval('+A1').direction_number
            1

            >>> abjad.NamedInterval('P1').direction_number
            0

            >>> abjad.NamedInterval('-m3').direction_number
            -1

        Returns ``-1``, ``0`` or ``1``.
        """
        if self.quality == "P" and abs(self.number) == 1:
            return 0
        return mathtools.sign(self.number)
示例#3
0
 def _from_interval_or_interval_class(self, argument):
     try:
         quality = argument.quality
         diatonic_number = abs(argument.number)
         direction = mathtools.sign(argument.number)
     except AttributeError:
         direction, quality, diatonic_number = self._numbered_to_named(
             argument)
     self._from_named_parts(direction, quality, diatonic_number)
示例#4
0
 def _from_interval_or_interval_class(self, argument):
     try:
         quality = argument.quality
         diatonic_number = abs(argument.number)
         direction = mathtools.sign(argument.number)
     except AttributeError:
         direction, quality, diatonic_number = self._numbered_to_named(
             argument
         )
     self._from_named_parts(direction, quality, diatonic_number)
示例#5
0
    def __str__(self):
        """
        String representation of numbered interval.

        Returns string.
        """
        direction_symbol = constants._direction_number_to_direction_symbol[
            mathtools.sign(self.number)
        ]
        return "{}{}".format(direction_symbol, abs(self.number))
示例#6
0
 def _from_number(self, argument):
     import abjad
     number = self._to_nearest_quarter_tone(argument)
     direction = mathtools.sign(number)
     octaves = 0
     pc_number = abs(number)
     while pc_number > 12:
         pc_number -= 12
         octaves += 1
     self._octaves = octaves
     self._interval_class = abjad.NumberedIntervalClass(pc_number *
                                                        direction)
示例#7
0
def test_init(input_, semitones, name):
    class_ = NamedInterval
    if (
        isinstance(semitones, type) and
        issubclass(semitones, Exception)
    ):
        with pytest.raises(semitones):
            class_(input_)
        return
    instance = class_(input_)
    assert float(instance) == semitones
    assert instance.name == name
    NamedInterval(instance)
    NumberedInterval(instance)
    NamedIntervalClass(instance)
    NumberedIntervalClass(instance)
    if isinstance(input_, str):
        group_dict = constants._interval_name_abbreviation_regex.match(
            input_).groupdict()
        inflected_up = class_('{}{}{}{}'.format(
            group_dict['direction'] or '',
            group_dict['quality'],
            '+',
            group_dict['number'],
            ))
        inflected_down = class_('{}{}{}{}'.format(
            group_dict['direction'] or '',
            group_dict['quality'],
            '~',
            group_dict['number'],
            ))
        if (
            (mathtools.sign(float(instance)) == instance.direction_number) and
            abs(instance.number) != 1
        ):
            direction = mathtools.sign(float(instance))
            assert float(inflected_up) == (abs(float(instance)) + 0.5) * direction
            assert float(inflected_down) == (abs(float(instance)) - 0.5) * direction
示例#8
0
    def _from_number(self, argument):
        import abjad

        number = self._to_nearest_quarter_tone(argument)
        direction = mathtools.sign(number)
        octaves = 0
        pc_number = abs(number)
        while pc_number > 12:
            pc_number -= 12
            octaves += 1
        self._octaves = octaves
        self._interval_class = abjad.NumberedIntervalClass(
            pc_number * direction
        )
示例#9
0
 def _numbered_to_named(cls, number):
     number = cls._to_nearest_quarter_tone(float(number))
     direction = mathtools.sign(number)
     octaves, semitones = divmod(abs(number), 12)
     quartertone = ""
     if semitones % 1:
         semitones -= 0.5
         quartertone = "+"
     quality, diatonic_number = constants._semitones_to_quality_and_diatonic_number[
         semitones]
     quality += quartertone
     diatonic_number += octaves * 7
     diatonic_number = cls._to_nearest_quarter_tone(diatonic_number)
     return direction, quality, diatonic_number
示例#10
0
    def number(self):
        """
        Gets number of named interval.

        ..  container:: example

            >>> abjad.NamedInterval('+M9').number
            9

        Returns nonnegative number.
        """
        number = self._interval_class._number
        direction = mathtools.sign(number)
        number = abs(number) + (7 * self.octaves)
        return number * direction
示例#11
0
文件: Interval.py 项目: Abjad/abjad
 def _numbered_to_named(cls, number):
     number = cls._to_nearest_quarter_tone(float(number))
     direction = mathtools.sign(number)
     octaves, semitones = divmod(abs(number), 12)
     quartertone = ""
     if semitones % 1:
         semitones -= 0.5
         quartertone = "+"
     quality, diatonic_number = constants._semitones_to_quality_and_diatonic_number[
         semitones
     ]
     quality += quartertone
     diatonic_number += octaves * 7
     diatonic_number = cls._to_nearest_quarter_tone(diatonic_number)
     return direction, quality, diatonic_number
示例#12
0
    def number(self):
        """
        Gets number of named interval.

        ..  container:: example

            >>> abjad.NamedInterval('+M9').number
            9

        Returns nonnegative number.
        """
        number = self._interval_class._number
        direction = mathtools.sign(number)
        number = abs(number) + (7 * self.octaves)
        return number * direction
示例#13
0
 def __init__(self, argument):
     import abjad
     if isinstance(argument, str):
         match = constants._interval_name_abbreviation_regex.match(argument)
         if match is None:
             try:
                 argument = float(argument)
                 self._from_number(argument)
                 return
             except ValueError:
                 message = 'can not initialize {} from {!r}.'
                 message = message.format(type(self).__name__, argument)
                 raise ValueError(message)
             message = 'can not initialize {} from {!r}.'
             message = message.format(type(self).__name__, argument)
             raise ValueError(message)
         group_dict = match.groupdict()
         direction = group_dict['direction']
         if direction == '-':
             direction = -1
         else:
             direction = 1
         quality = group_dict['quality']
         diatonic_number = int(group_dict['number'])
         quality = self._validate_quality_and_diatonic_number(
             quality,
             diatonic_number,
         )
         quartertone = group_dict['quartertone']
         quality += quartertone
         self._from_named_parts(direction, quality, diatonic_number)
     elif isinstance(argument, tuple) and len(argument) == 2:
         quality, number = argument
         direction = mathtools.sign(number)
         diatonic_number = abs(number)
         quality = self._validate_quality_and_diatonic_number(
             quality,
             diatonic_number,
         )
         self._from_named_parts(direction, quality, diatonic_number)
     elif isinstance(argument, numbers.Number):
         self._from_number(argument)
     elif isinstance(argument, (abjad.Interval, abjad.IntervalClass)):
         self._from_interval_or_interval_class(argument)
     else:
         message = 'can not initialize {} from {!r}.'
         message = message.format(type(self).__name__, argument)
         raise ValueError(message)
示例#14
0
    def __init__(self, argument):
        import abjad

        if isinstance(argument, str):
            match = constants._interval_name_abbreviation_regex.match(argument)
            if match is None:
                try:
                    argument = float(argument)
                    self._from_number(argument)
                    return
                except ValueError:
                    message = "can not initialize {} from {!r}."
                    message = message.format(type(self).__name__, argument)
                    raise ValueError(message)
                message = "can not initialize {} from {!r}."
                message = message.format(type(self).__name__, argument)
                raise ValueError(message)
            group_dict = match.groupdict()
            direction = group_dict["direction"]
            if direction == "-":
                direction = -1
            else:
                direction = 1
            quality = group_dict["quality"]
            diatonic_number = int(group_dict["number"])
            quality = self._validate_quality_and_diatonic_number(
                quality, diatonic_number
            )
            quartertone = group_dict["quartertone"]
            quality += quartertone
            self._from_named_parts(direction, quality, diatonic_number)
        elif isinstance(argument, tuple) and len(argument) == 2:
            quality, number = argument
            direction = mathtools.sign(number)
            diatonic_number = abs(number)
            quality = self._validate_quality_and_diatonic_number(
                quality, diatonic_number
            )
            self._from_named_parts(direction, quality, diatonic_number)
        elif isinstance(argument, numbers.Number):
            self._from_number(argument)
        elif isinstance(argument, (abjad.Interval, abjad.IntervalClass)):
            self._from_interval_or_interval_class(argument)
        else:
            message = "can not initialize {} from {!r}."
            message = message.format(type(self).__name__, argument)
            raise ValueError(message)
示例#15
0
    def direction_number(self):
        """
        Gets direction number of numbered interval.

        ..  container:: example

            >>> abjad.NumberedInterval(-14).direction_number
            -1

            >>> abjad.NumberedInterval(0).direction_number
            0

            >>> abjad.NumberedInterval(6).direction_number
            1

        Returns integer.
        """ ""
        return mathtools.sign(self.number)
示例#16
0
    def direction_number(self):
        """
        Gets direction number of numbered interval.

        ..  container:: example

            >>> abjad.NumberedInterval(-14).direction_number
            -1

            >>> abjad.NumberedInterval(0).direction_number
            0

            >>> abjad.NumberedInterval(6).direction_number
            1

        Returns integer.
        """ ""
        return mathtools.sign(self.number)
示例#17
0
    def direction_number(self):
        """
        Gets direction number of named interval-class.

        ..  container:: example

            >>> abjad.NamedIntervalClass('P1').direction_number
            0

            >>> abjad.NamedIntervalClass('+M2').direction_number
            1

            >>> abjad.NamedIntervalClass('-M2').direction_number
            -1

        Returns -1, 0 or 1.
        """
        if self.quality == "P" and abs(self.number) == 1:
            return 0
        return mathtools.sign(self.number)
示例#18
0
    def direction_number(self):
        """
        Gets direction number of named interval-class.

        ..  container:: example

            >>> abjad.NamedIntervalClass('P1').direction_number
            0

            >>> abjad.NamedIntervalClass('+M2').direction_number
            1

            >>> abjad.NamedIntervalClass('-M2').direction_number
            -1

        Returns -1, 0 or 1.
        """
        if self.quality == 'P' and abs(self.number) == 1:
            return 0
        return mathtools.sign(self.number)
示例#19
0
    def number(self):
        """
        Gets number of numbered interval.

        ..  container:: example

            >>> abjad.NumberedInterval(-14).number
            -14

            >>> abjad.NumberedInterval(-2).number
            -2

            >>> abjad.NumberedInterval(0).number
            0

        Returns number.
        """
        number = self._interval_class._number
        direction = mathtools.sign(number)
        number = abs(number) + (12 * self.octaves)
        return number * direction
示例#20
0
    def number(self):
        """
        Gets number of numbered interval.

        ..  container:: example

            >>> abjad.NumberedInterval(-14).number
            -14

            >>> abjad.NumberedInterval(-2).number
            -2

            >>> abjad.NumberedInterval(0).number
            0

        Returns number.
        """
        number = self._interval_class._number
        direction = mathtools.sign(number)
        number = abs(number) + (12 * self.octaves)
        return number * direction
示例#21
0
    def _named_to_numbered(cls, direction, quality, diatonic_number):
        octave_number = 0
        diatonic_pc_number = abs(diatonic_number)
        while diatonic_pc_number >= 8:
            diatonic_pc_number -= 7
            octave_number += 1

        quartertone = ""
        if quality.endswith(("+", "~")):
            quality, quartertone = quality[:-1], quality[-1]

        base_quality = quality
        if base_quality == "P" and octave_number and diatonic_pc_number == 1:
            return 12 * direction
        if len(quality) > 1:
            base_quality = quality[0]

        semitones = constants._diatonic_number_and_quality_to_semitones[
            diatonic_pc_number
        ][base_quality]
        if base_quality == "d":
            semitones -= len(quality) - 1
        elif base_quality == "A":
            semitones += len(quality) - 1

        if quartertone == "+":
            semitones += 0.5
        elif quartertone == "~":
            semitones -= 0.5

        if abs(diatonic_number) == 1:
            semitones = abs(semitones)
        while abs(semitones) > 12:
            semitones = (abs(semitones) - 12) * mathtools.sign(semitones)
        semitones *= direction
        return mathtools.integer_equivalent_number_to_integer(semitones)
示例#22
0
    def _named_to_numbered(cls, direction, quality, diatonic_number):
        octave_number = 0
        diatonic_pc_number = abs(diatonic_number)
        while diatonic_pc_number >= 8:
            diatonic_pc_number -= 7
            octave_number += 1

        quartertone = ""
        if quality.endswith(("+", "~")):
            quality, quartertone = quality[:-1], quality[-1]

        base_quality = quality
        if base_quality == "P" and octave_number and diatonic_pc_number == 1:
            return 12 * direction
        if len(quality) > 1:
            base_quality = quality[0]

        semitones = constants._diatonic_number_and_quality_to_semitones[
            diatonic_pc_number
        ][base_quality]
        if base_quality == "d":
            semitones -= len(quality) - 1
        elif base_quality == "A":
            semitones += len(quality) - 1

        if quartertone == "+":
            semitones += 0.5
        elif quartertone == "~":
            semitones -= 0.5

        if abs(diatonic_number) == 1:
            semitones = abs(semitones)
        while abs(semitones) > 12:
            semitones = (abs(semitones) - 12) * mathtools.sign(semitones)
        semitones *= direction
        return mathtools.integer_equivalent_number_to_integer(semitones)
示例#23
0
import pytest
from abjad import mathtools
from abjad.pitch import (
    NamedInterval,
    NamedIntervalClass,
    NumberedInterval,
    NumberedIntervalClass,
)


values = []

values.extend(
    (x, ((abs(x) % 12) or 12) * mathtools.sign(x)) for x in range(-48, 49)
)

values.extend(
    [
        ("-A1", -1),
        ("-A10", -5),
        ("-A11", -6),
        ("-A12", -8),
        ("-A13", -10),
        ("-A14", -12),
        ("-A2", -3),
        ("-A3", -5),
        ("-A4", -6),
        ("-A5", -8),
        ("-A6", -10),
        ("-A7", -12),
        ("-A8", -1),
示例#24
0
def partition_integer_by_ratio(n, ratio):
    """
    Partitions positive integer-equivalent ``n`` by ``ratio``.

    ..  container:: example

        >>> abjad.mathtools.partition_integer_by_ratio(10, [1, 2])
        [3, 7]

    ..  container:: example

        Partitions positive integer-equivalent ``n`` by ``ratio`` with negative
        parts:

        >>> abjad.mathtools.partition_integer_by_ratio(10, [1, -2])
        [3, -7]

    ..  container:: example

        Partitions negative integer-equivalent ``n`` by ``ratio``:

        >>> abjad.mathtools.partition_integer_by_ratio(-10, [1, 2])
        [-3, -7]

    ..  container:: example

        Partitions negative integer-equivalent ``n`` by ``ratio`` with negative
        parts:

        >>> abjad.mathtools.partition_integer_by_ratio(-10, [1, -2])
        [-3, 7]

    ..  container:: example

        More examples:

        >>> abjad.mathtools.partition_integer_by_ratio(10, [1])
        [10]

        >>> abjad.mathtools.partition_integer_by_ratio(10, [1, 1])
        [5, 5]

        >>> abjad.mathtools.partition_integer_by_ratio(10, [1, -1, -1])
        [3, -4, -3]

        >>> abjad.mathtools.partition_integer_by_ratio(-10, [1, 1, 1, 1])
        [-3, -2, -3, -2]

        >>> abjad.mathtools.partition_integer_by_ratio(-10, [1, 1, 1, 1, 1])
        [-2, -2, -2, -2, -2]

    Returns result with weight equal to absolute value of ``n``.

    Returns list of integers.
    """
    from abjad import mathtools

    if not mathtools.is_integer_equivalent_number(n):
        message = "is not integer-equivalent number: {!r}."
        message = message.format(n)
        raise TypeError(message)
    ratio = mathtools.Ratio(ratio).numbers
    if not all(mathtools.is_integer_equivalent_number(part) for part in ratio):
        message = "some parts in {!r} not integer-equivalent numbers."
        message = message.format(ratio)
        raise TypeError(message)
    result = [0]
    divisions = [
        float(abs(n)) * abs(part) / mathtools.weight(ratio) for part in ratio
    ]
    cumulative_divisions = mathtools.cumulative_sums(divisions, start=None)
    for division in cumulative_divisions:
        rounded_division = int(round(division)) - sum(result)
        if division - round(division) == 0.5:
            rounded_division += 1
        result.append(rounded_division)
    result = result[1:]
    if mathtools.sign(n) == -1:
        result = [-x for x in result]
    ratio_signs = [mathtools.sign(x) for x in ratio]
    result = [pair[0] * pair[1] for pair in zip(ratio_signs, result)]
    return result
示例#25
0
def partition_integer_by_ratio(n, ratio):
    """
    Partitions positive integer-equivalent ``n`` by ``ratio``.

    ..  container:: example

        >>> abjad.mathtools.partition_integer_by_ratio(10, [1, 2])
        [3, 7]

    ..  container:: example

        Partitions positive integer-equivalent ``n`` by ``ratio`` with negative
        parts:

        >>> abjad.mathtools.partition_integer_by_ratio(10, [1, -2])
        [3, -7]

    ..  container:: example

        Partitions negative integer-equivalent ``n`` by ``ratio``:

        >>> abjad.mathtools.partition_integer_by_ratio(-10, [1, 2])
        [-3, -7]

    ..  container:: example

        Partitions negative integer-equivalent ``n`` by ``ratio`` with negative
        parts:

        >>> abjad.mathtools.partition_integer_by_ratio(-10, [1, -2])
        [-3, 7]

    ..  container:: example

        More examples:

        >>> abjad.mathtools.partition_integer_by_ratio(10, [1])
        [10]

        >>> abjad.mathtools.partition_integer_by_ratio(10, [1, 1])
        [5, 5]

        >>> abjad.mathtools.partition_integer_by_ratio(10, [1, -1, -1])
        [3, -4, -3]

        >>> abjad.mathtools.partition_integer_by_ratio(-10, [1, 1, 1, 1])
        [-3, -2, -3, -2]

        >>> abjad.mathtools.partition_integer_by_ratio(-10, [1, 1, 1, 1, 1])
        [-2, -2, -2, -2, -2]

    Returns result with weight equal to absolute value of ``n``.

    Returns list of integers.
    """
    from abjad import mathtools
    if not mathtools.is_integer_equivalent_number(n):
        message = 'is not integer-equivalent number: {!r}.'
        message = message.format(n)
        raise TypeError(message)
    ratio = mathtools.Ratio(ratio).numbers
    if not all(mathtools.is_integer_equivalent_number(part) for part in ratio):
        message = 'some parts in {!r} not integer-equivalent numbers.'
        message = message.format(ratio)
        raise TypeError(message)
    result = [0]
    divisions = [
        float(abs(n)) * abs(part) / mathtools.weight(ratio) for part in ratio
    ]
    cumulative_divisions = mathtools.cumulative_sums(divisions, start=None)
    for division in cumulative_divisions:
        rounded_division = int(round(division)) - sum(result)
        if division - round(division) == 0.5:
            rounded_division += 1
        result.append(rounded_division)
    result = result[1:]
    if mathtools.sign(n) == -1:
        result = [-x for x in result]
    ratio_signs = [mathtools.sign(x) for x in ratio]
    result = [pair[0] * pair[1] for pair in zip(ratio_signs, result)]
    return result
示例#26
0
 def _sibling(self, n):
     assert n in (-1, 1), repr(n)
     for parent in inspect(self).parentage():
         sibling = parent.__sibling(mathtools.sign(n))
         if sibling is not None:
             return sibling
示例#27
0
    def from_pitch_carriers(class_, pitch_carrier_1, pitch_carrier_2):
        """
        Makes named interval calculated from `pitch_carrier_1` to
        `pitch_carrier_2`.

        ..  container:: example

            >>> abjad.NamedInterval.from_pitch_carriers(
            ...     abjad.NamedPitch(-2),
            ...     abjad.NamedPitch(12),
            ...     )
            NamedInterval('+M9')

            >>> abjad.NamedInterval.from_pitch_carriers(
            ...     abjad.NamedPitch("css'"),
            ...     abjad.NamedPitch("cff'"),
            ...     )
            NamedInterval('-AAAA1')

            >>> abjad.NamedInterval.from_pitch_carriers("c'", "cs'''")
            NamedInterval('+A15')

            >>> abjad.NamedInterval.from_pitch_carriers('c', 'cqs')
            NamedInterval('+P+1')

            >>> abjad.NamedInterval.from_pitch_carriers("cf'", 'bs')
            NamedInterval('-dd2')

            >>> abjad.NamedInterval.from_pitch_carriers("cff'", 'aqs')
            NamedInterval('-ddd+3')

            >>> abjad.NamedInterval.from_pitch_carriers("cff'", 'atqs')
            NamedInterval('-dddd+3')

        Returns named interval.
        """
        import abjad

        pitch_1 = abjad.NamedPitch(pitch_carrier_1)
        pitch_2 = abjad.NamedPitch(pitch_carrier_2)
        degree_1 = pitch_1._get_diatonic_pitch_number()
        degree_2 = pitch_2._get_diatonic_pitch_number()
        named_sign = mathtools.sign(degree_1 - degree_2)
        named_i_number = abs(degree_1 - degree_2) + 1
        numbered_sign = mathtools.sign(
            float(abjad.NumberedPitch(pitch_1)) -
            float(abjad.NumberedPitch(pitch_2)))
        numbered_i_number = abs(
            float(abjad.NumberedPitch(pitch_1)) -
            float(abjad.NumberedPitch(pitch_2)))
        named_ic_number = named_i_number
        numbered_ic_number = numbered_i_number

        while named_ic_number > 8 and numbered_ic_number > 12:
            named_ic_number -= 7
            numbered_ic_number -= 12

        # Multiply-diminished intervals can have opposite signs
        if named_sign and (named_sign == -numbered_sign):
            numbered_ic_number *= -1

        quartertone = ""
        if numbered_ic_number % 1:
            quartertone = "+"
            numbered_ic_number -= 0.5

        mapping = {
            value: key
            for key, value in constants.
            _diatonic_number_and_quality_to_semitones[named_ic_number].items()
        }

        quality = ""

        while numbered_ic_number > max(mapping):
            numbered_ic_number -= 1
            quality += "A"

        while numbered_ic_number < min(mapping):
            numbered_ic_number += 1
            quality += "d"

        quality += mapping[numbered_ic_number]
        quality += quartertone
        direction = 1
        if pitch_2 < pitch_1:
            direction = -1

        return class_((quality, named_i_number * direction))
def partition_integer_into_canonic_parts(n, decrease_parts_monotonically=True):
    """
    Partitions integer ``n`` into canonic parts.

    ..  container:: example

        Returns all parts positive on positive ``n``:

        >>> for n in range(1, 11):
        ...     print(n, abjad.mathtools.partition_integer_into_canonic_parts(n))
        ...
        1 (1,)
        2 (2,)
        3 (3,)
        4 (4,)
        5 (4, 1)
        6 (6,)
        7 (7,)
        8 (8,)
        9 (8, 1)
        10 (8, 2)

    ..  container:: example

        Returns all parts negative on negative ``n``:

        >>> for n in reversed(range(-20, -10)):
        ...     print(n, abjad.mathtools.partition_integer_into_canonic_parts(n))
        ...
        -11 (-8, -3)
        -12 (-12,)
        -13 (-12, -1)
        -14 (-14,)
        -15 (-15,)
        -16 (-16,)
        -17 (-16, -1)
        -18 (-16, -2)
        -19 (-16, -3)
        -20 (-16, -4)

    ..  container:: example

        Returns parts that increase monotonically:

        >>> for n in range(11, 21):
        ...     print(n, abjad.mathtools.partition_integer_into_canonic_parts(n,
        ...         decrease_parts_monotonically=False))
        ...
        11 (3, 8)
        12 (12,)
        13 (1, 12)
        14 (14,)
        15 (15,)
        16 (16,)
        17 (1, 16)
        18 (2, 16)
        19 (3, 16)
        20 (4, 16)

    Returns tuple with parts that decrease monotonically.

    Returns tuple of integers.
    """
    from abjad import mathtools

    assert isinstance(n, int), repr(n)
    assert isinstance(decrease_parts_monotonically, bool)
    if n == 0:
        return (0,)
    result = []
    previous_empty = True
    binary_n = mathtools.integer_to_binary_string(abs(n))
    binary_length = len(binary_n)
    for i, character in enumerate(binary_n):
        if character == "1":
            place_value = 2 ** (binary_length - i - 1)
            if previous_empty:
                result.append(place_value)
            else:
                result[-1] += place_value
            previous_empty = False
        else:
            previous_empty = True
    sign_n = mathtools.sign(n)
    if mathtools.sign(n) == -1:
        result = [sign_n * _ for _ in result]
    if decrease_parts_monotonically:
        return tuple(result)
    else:
        return tuple(reversed(result))
示例#29
0
    def from_pitch_carriers(class_, pitch_carrier_1, pitch_carrier_2):
        """
        Makes named interval calculated from `pitch_carrier_1` to
        `pitch_carrier_2`.

        ..  container:: example

            >>> abjad.NamedInterval.from_pitch_carriers(
            ...     abjad.NamedPitch(-2),
            ...     abjad.NamedPitch(12),
            ...     )
            NamedInterval('+M9')

            >>> abjad.NamedInterval.from_pitch_carriers(
            ...     abjad.NamedPitch("css'"),
            ...     abjad.NamedPitch("cff'"),
            ...     )
            NamedInterval('-AAAA1')

            >>> abjad.NamedInterval.from_pitch_carriers("c'", "cs'''")
            NamedInterval('+A15')

            >>> abjad.NamedInterval.from_pitch_carriers('c', 'cqs')
            NamedInterval('+P+1')

            >>> abjad.NamedInterval.from_pitch_carriers("cf'", 'bs')
            NamedInterval('-dd2')

            >>> abjad.NamedInterval.from_pitch_carriers("cff'", 'aqs')
            NamedInterval('-ddd+3')

            >>> abjad.NamedInterval.from_pitch_carriers("cff'", 'atqs')
            NamedInterval('-dddd+3')

        Returns named interval.
        """
        import abjad

        pitch_1 = abjad.NamedPitch(pitch_carrier_1)
        pitch_2 = abjad.NamedPitch(pitch_carrier_2)
        degree_1 = pitch_1._get_diatonic_pitch_number()
        degree_2 = pitch_2._get_diatonic_pitch_number()
        named_sign = mathtools.sign(degree_1 - degree_2)
        named_i_number = abs(degree_1 - degree_2) + 1
        numbered_sign = mathtools.sign(
            float(abjad.NumberedPitch(pitch_1))
            - float(abjad.NumberedPitch(pitch_2))
        )
        numbered_i_number = abs(
            float(abjad.NumberedPitch(pitch_1))
            - float(abjad.NumberedPitch(pitch_2))
        )
        named_ic_number = named_i_number
        numbered_ic_number = numbered_i_number

        while named_ic_number > 8 and numbered_ic_number > 12:
            named_ic_number -= 7
            numbered_ic_number -= 12

        # Multiply-diminished intervals can have opposite signs
        if named_sign and (named_sign == -numbered_sign):
            numbered_ic_number *= -1

        quartertone = ""
        if numbered_ic_number % 1:
            quartertone = "+"
            numbered_ic_number -= 0.5

        mapping = {
            value: key
            for key, value in constants._diatonic_number_and_quality_to_semitones[
                named_ic_number
            ].items()
        }

        quality = ""

        while numbered_ic_number > max(mapping):
            numbered_ic_number -= 1
            quality += "A"

        while numbered_ic_number < min(mapping):
            numbered_ic_number += 1
            quality += "d"

        quality += mapping[numbered_ic_number]
        quality += quartertone
        direction = 1
        if pitch_2 < pitch_1:
            direction = -1

        return class_((quality, named_i_number * direction))
示例#30
0
def partition_integer_into_canonic_parts(n, decrease_parts_monotonically=True):
    """
    Partitions integer ``n`` into canonic parts.

    ..  container:: example

        Returns all parts positive on positive ``n``:

        >>> for n in range(1, 11):
        ...     print(n, abjad.mathtools.partition_integer_into_canonic_parts(n))
        ...
        1 (1,)
        2 (2,)
        3 (3,)
        4 (4,)
        5 (4, 1)
        6 (6,)
        7 (7,)
        8 (8,)
        9 (8, 1)
        10 (8, 2)

    ..  container:: example

        Returns all parts negative on negative ``n``:

        >>> for n in reversed(range(-20, -10)):
        ...     print(n, abjad.mathtools.partition_integer_into_canonic_parts(n))
        ...
        -11 (-8, -3)
        -12 (-12,)
        -13 (-12, -1)
        -14 (-14,)
        -15 (-15,)
        -16 (-16,)
        -17 (-16, -1)
        -18 (-16, -2)
        -19 (-16, -3)
        -20 (-16, -4)

    ..  container:: example

        Returns parts that increase monotonically:

        >>> for n in range(11, 21):
        ...     print(n, abjad.mathtools.partition_integer_into_canonic_parts(n,
        ...         decrease_parts_monotonically=False))
        ...
        11 (3, 8)
        12 (12,)
        13 (1, 12)
        14 (14,)
        15 (15,)
        16 (16,)
        17 (1, 16)
        18 (2, 16)
        19 (3, 16)
        20 (4, 16)

    Returns tuple with parts that decrease monotonically.

    Returns tuple of integers.
    """
    from abjad import mathtools
    assert isinstance(n, int), repr(n)
    assert isinstance(decrease_parts_monotonically, bool)
    if n == 0:
        return (0, )
    result = []
    previous_empty = True
    binary_n = mathtools.integer_to_binary_string(abs(n))
    binary_length = len(binary_n)
    for i, character in enumerate(binary_n):
        if character == '1':
            place_value = 2**(binary_length - i - 1)
            if previous_empty:
                result.append(place_value)
            else:
                result[-1] += place_value
            previous_empty = False
        else:
            previous_empty = True
    sign_n = mathtools.sign(n)
    if mathtools.sign(n) == -1:
        result = [sign_n * _ for _ in result]
    if decrease_parts_monotonically:
        return tuple(result)
    else:
        return tuple(reversed(result))
示例#31
0
文件: Component.py 项目: Abjad/abjad
 def _sibling(self, n):
     assert n in (-1, 1), repr(n)
     for parent in inspect(self).parentage():
         sibling = parent.__sibling(mathtools.sign(n))
         if sibling is not None:
             return sibling
示例#32
0
import pytest
from abjad import mathtools
from abjad.pitch import (
    NamedInterval,
    NamedIntervalClass,
    NumberedInterval,
    NumberedIntervalClass,
)

values = []

values.extend(
    (x, ((abs(x) % 12) or 12) * mathtools.sign(x)) for x in range(-48, 49))

values.extend([
    ('-A1', -1),
    ('-A10', -5),
    ('-A11', -6),
    ('-A12', -8),
    ('-A13', -10),
    ('-A14', -12),
    ('-A2', -3),
    ('-A3', -5),
    ('-A4', -6),
    ('-A5', -8),
    ('-A6', -10),
    ('-A7', -12),
    ('-A8', -1),
    ('-A9', -3),
    ('-AA1', -2),
    ('-AA10', -6),