Copy edit documentation after suggestions from B.P. Leonard

This commit is contained in:
Jonathan Harker 2024-10-12 16:07:19 +13:00
parent 64dd35e1f8
commit 640a1440b3

View file

@ -7,7 +7,7 @@ import re
class SetClass(list):
"""
Musical set class, containing zero or more pitch classes. This implementation can handle set
classes of any arbitrary :attr:`tonality`, or number of divisions of the octave.
classes of any arbitrary :attr:`tonality`, or number of uniform divisions of the octave.
"""
def __init__(self, *args: int, tonality: int = 12) -> None:
@ -15,8 +15,8 @@ class SetClass(list):
Instantiate a :class:`ClassSet` object with a series of integers.
Each supplied pitch class is "normalised" by modulo the :attr:`tonality`, the set is
sorted in ascending order, and values are transposed (rotated) until the lowest value is 0.
For a number of divisions of the octave other than the default (Western harmony) value of
sorted in ascending order, and values are transposed until the lowest pitch class value is
0. For a number of divisions of the octave other than the default (Western harmony) value of
12, supply an integer value using the 'tonality' keyword. Example:
>>> sc1 = SetClass(0, 7, 9)
@ -30,7 +30,7 @@ class SetClass(list):
*args (int):
The pitch class values.
tonality (int):
The :attr:`tonality`, or modulus, is the number of divisions of the octave.
The :attr:`tonality`, or modulus, is the number of uniform divisions of the octave.
If unspecified, the default value of 12 is assumed (Western harmony).
"""
self._tonality = tonality
@ -69,7 +69,7 @@ class SetClass(list):
@cached_property
def tonality(self) -> int:
"""
The number of (equal) divisions of the octave. The default value is 12, which
The number of uniform divisions of the octave. The default value is 12, which
represents traditional Western chromatic harmony, the octave divided into twelve semitones.
"""
return self._tonality
@ -87,7 +87,7 @@ class SetClass(list):
The brightness of the set class.
Brightness (B) is a property proposed by Brian Leonard, defined as the sum of the values of
the :attr:`pitch_classes`.
the :attr:`pitch_classes` in the set class.
"""
return sum(self.pitch_classes)
@ -97,8 +97,8 @@ class SetClass(list):
The decimal value of the binary representation of the :attr:`pitch_classes`.
Returns the decimal value of the pitch classes expressed as a binary bit mask, i.e. the sum
of 2 where i is each pitch class value. For example, set class {0,1,4,6} has a binary value
of 000001010011, which is the decimal value 83.
of 2 where i is each pitch class value in ascending order. For example, set class {0,1,4,6}
has a binary value of 000001010011, which is the decimal value 83.
Further reading: Goyette (2012) p. 25, citing Brinkman (1986).
"""
@ -118,22 +118,6 @@ class SetClass(list):
intervals.append(self.tonality - prev)
return intervals
@cached_property
def z_relations(self) -> list:
"""
A :class:`list` of the Z-relations of this set class.
Allen Forte in his book *The Structure of Atonal Music* (1973) described the relationship
between twins of set classes that share the same :attr:`interval_vector`, but are not
related by :attr:`inversion`, :attr:`complement`, or transposition (rotation), as Z-related
('Z' for *zygote* from Greek: ζυγωτός, 'joined'). This property returns all distinct set
classes with the same interval vector.
For example, Forte 4-Z15 {0,1,4,6} and Forte 4-Z29 {0,1,3,7} both have iv1,1,1,1,1,1 but
are not inversions, complements, or transpositions (rotations) of each other.
"""
return [i for i in SetClass.darkest_of_cardinality(self.cardinality) if i.interval_vector == self.interval_vector]
@cached_property
def interval_vector(self) -> list:
"""
@ -150,6 +134,22 @@ class SetClass(list):
iv[ic - 1] += 1
return iv
@cached_property
def z_relations(self) -> list:
"""
A :class:`list` of the Z-relations of this set class.
Allen Forte in his book *The Structure of Atonal Music* (1973) described the relationship
between twins of set classes that share the same :attr:`interval_vector`, but are not
related by :attr:`inversion`, :attr:`complement`, or transposition, as Z-related ('Z' for
*zygote* from Greek: ζυγωτός, 'joined' or 'paired'). This property returns all distinct set
classes with the same interval vector.
For example, Forte 4-Z15 {0,1,4,6} and Forte 4-Z29 {0,1,3,7} both have iv1,1,1,1,1,1 but
are not inversions, complements, or transpositions of each other.
"""
return [i for i in SetClass.darkest_of_cardinality(self.cardinality) if i.interval_vector == self.interval_vector]
def ordered_interval(self, a: int, b: int) -> int:
"""
Return the ordered interval of two pitch classes.
@ -195,8 +195,8 @@ class SetClass(list):
@cached_property
def versions(self) -> list(SetClass):
"""
All possible zero-normalised transpositions (rotations) of this set class, sorted by
:attr:`brightness`. See Rahn (1980), Tₙ set types.
All possible zero-normalised transpositions of this set class, sorted by :attr:`brightness`.
See Rahn (1980), Tₙ set types.
"""
# The empty set class has one version, itself
if not self.pitch_classes:
@ -216,10 +216,10 @@ class SetClass(list):
The Rahn normal form of the set class.
John Rahn's normal form described in his book *Basic Atonal Theory* (1980) is an algorithm
to produce a unique form for each set class (see :attr:`rahn_normal_form`). Often wrongly
described as "most packed to the left", Leonard describes it as "most dispersed from the
right". Find the smallest outside interval, and if necessary proceed inwards from the right
finding the smallest next interval until one result remains. See Rahn (1980), p. 33.
to produce a unique form for each set class. Often wrongly described as "most packed to the
left", Leonard describes it as "most dispersed from the right". Find the smallest outside
interval, and if necessary proceed inwards from the right finding the smallest next interval
until one result remains. See Rahn (1980), p. 33.
"""
def _most_dispersed(versions, n):
return [i for i in versions if i.pitch_classes[-n] == min([i.pitch_classes[-n] for i in versions])]
@ -231,6 +231,15 @@ class SetClass(list):
n += 1
return versions[0]
@cached_property
def rahn_prime_form(self) -> SetClass:
"""
The Rahn prime is the most dispersed from the right of the Rahn normal forms of a set class
and its inversion.
"""
prime = min(self.rahn_normal_form.decimal, self.inversion.rahn_normal_form.decimal)
return self.inversion.rahn_normal_form if self.inversion.rahn_normal_form.decimal == prime else self.inversion.rahn_normal_form
@cached_property
def packed_left(self) -> SetClass:
"""
@ -314,9 +323,15 @@ class SetClass(list):
@cached_property
def is_symmetrical(self) -> bool:
"""
Whether this set class is symmetrical upon inversion, for example Forte 5-Z17:
Whether this set class is symmetrical upon inversion, for example Forte 5-Z37:
{0,1,2,5,9} {0,4,8,9,11}
>>> sc = SetClass(0, 1, 2, 5, 9)
>>> sc.rahn_normal_form
SetClass{0,3,4,5,8}
>>> sc.inversion.rahn_normal_form
SetClass{0,3,4,5,8}
>>> sc.is_symmetrical
True
"""
return self.darkest_form == self.inversion.darkest_form
@ -400,7 +415,7 @@ class SetClass(list):
string (str):
Any string representation of a set class, containing some integer content.
tonality (int):
The :attr:`tonality`, or modulus, is the number of divisions of the octave.
The :attr:`tonality`, or modulus, is the number of uniform divisions of the octave.
If unspecified, the default value of 12 is assumed (Western harmony).
Returns:
@ -421,7 +436,7 @@ class SetClass(list):
cardinality (int):
The :attr:`cardinality` of the set classes to return.
tonality (int):
The :attr:`tonality`, or modulus, is the number of divisions of the octave.
The :attr:`tonality`, or modulus, is the number of uniform divisions of the octave.
If unspecified, the default value of 12 is assumed (Western harmony).
Returns:
@ -445,8 +460,8 @@ class SetClass(list):
their darkest forms.
This produces a smaller set than :attr:`all_of_cardinality`, since it eliminates set classes
that are "brighter" transpositions (rotations) of the darkest :class:`SetClass` returned by
the :attr:`darkest_form` property.
that are "brighter" transpositions of the darkest :class:`SetClass` returned by the
:attr:`darkest_form` property.
.. warning:: High values of tonality can take a long time to calculate (T=24 takes about a
minute on an Intel i7-13700H CPU).
@ -455,7 +470,7 @@ class SetClass(list):
cardinality (int):
The :attr:`cardinality` of the set classes to return.
tonality (int):
The :attr:`tonality`, or modulus, is the number of divisions of the octave.
The :attr:`tonality`, or modulus, is the number of uniform divisions of the octave.
If unspecified, the default value of 12 is assumed (Western harmony).
Returns:
@ -470,7 +485,7 @@ class SetClass(list):
their Rahn normal form.
This produces a smaller set than :attr:`all_of_cardinality`, since it eliminates set classes
that are transpositions (rotations) of the normalised :class:`SetClass` returned by the
that are transpositions of the normalised :class:`SetClass` returned by the
:attr:`rahn_normal_form` property.
.. warning:: High values of tonality can take a long time to calculate (T=24 takes about a
@ -480,7 +495,7 @@ class SetClass(list):
cardinality (int):
The :attr:`cardinality` of the set classes to return.
tonality (int):
The :attr:`tonality`, or modulus, is the number of divisions of the octave.
The :attr:`tonality`, or modulus, is the number of uniform divisions of the octave.
If unspecified, the default value of 12 is assumed (Western harmony).
Returns: