music21.sieve¶
A comprehensive, object model of the Xenakis Sieve. music21.sieve.Sieve
objects can be created from high-level string notations, and used to generate line segments
in various representation. Additional functionality is available through associated objects.
The music21.sieve.Sieve
class permits generation segments in four formats.
>>> a = sieve.Sieve('3@2|7@1')
>>> a.segment()
[1, 2, 5, 8, 11, 14, 15, 17, 20, 22, 23, 26, 29, 32, 35, 36, 38, 41, 43, 44,
47, 50, 53, 56, 57, 59, 62, 64, 65, 68, 71, 74, 77, 78, 80, 83, 85, 86, 89, 92, 95, 98, 99]
>>> a.segment(segmentFormat='binary')
[0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1,
0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1,
0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1,
0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1]
>>> a.segment(segmentFormat='width')
[1, 3, 3, 3, 3, 1, 2, 3, 2, 1, 3, 3, 3, 3, 1, 2, 3, 2, 1, 3, 3, 3, 3, 1, 2, 3, 2,
1, 3, 3, 3, 3, 1, 2, 3, 2, 1, 3, 3, 3, 3, 1]
>>> len(a.segment(segmentFormat='unit'))
43
A music21.sieve.CompressionSegment
can be used to derive a Sieve from a
ny sequence of integers.
>>> a = sieve.CompressionSegment([3, 4, 5, 6, 7, 8, 13, 19])
>>> str(a)
'6@1|7@6|8@5|9@4|10@3|11@8'
The music21.sieve.PitchSieve
class provides a quick generation of
music21.pitch.Pitch
lists from Sieves.
>>> a = sieve.PitchSieve('13@3|13@6|13@9', 'c1', 'c10', 'f#4')
>>> pitches = a()
>>> ', '.join([str(p) for p in pitches])
'F#1, A1, C2, G2, B-2, C#3, G#3, B3, D4, A4, C5, E-5, B-5, C#6, E6, B6, D7,
F7, C8, E-8, F#8, C#9, E9, G9'
CompressionSegment¶
- class music21.sieve.CompressionSegment(src, z=None)¶
Utility to convert from a point sequence to sieve.
A z range can be supplied to explicitly provide the complete sieve segment, both positive and negative values. all values in the z range not in the segment are interpreted as negative values. thus, there is an essential dependency on the z range and the realized sieve.
No matter the size of the z range, there is a modulus at which one point in the segment can be found. As such, any segment can be reduced to, at a minimum, a residual for each point in the segment, each, for the supplied z, providing a segment with one point.
The same segment can then have multiplied logical string representations, depending on the provided z.
>>> a = sieve.CompressionSegment([3, 4, 5, 6, 7, 8, 13, 19]) >>> str(a) '6@1|7@6|8@5|9@4|10@3|11@8'
>>> b = sieve.CompressionSegment([0, 2, 4, 6, 8]) >>> str(b) '2@0'
>>> c = sieve.CompressionSegment([0, 2, 4, 5, 7, 9, 11, 12]) >>> str(c) '5@2|5@4|6@5|7@0'
PitchSieve¶
- class music21.sieve.PitchSieve(sieveString, pitchLower: str | None = None, pitchUpper: str | None = None, pitchOrigin: str | None = None, eld: int | float = 1)¶
Quick utility generator of
music21.pitch.Pitch
lists frommusic21.sieve.Sieve
objects.>>> ps = sieve.PitchSieve('6@0', 'c4', 'c8') >>> [str(p) for p in ps()] ['C4', 'F#4', 'C5', 'F#5', 'C6', 'F#6', 'C7', 'F#7', 'C8']
>>> a = sieve.PitchSieve('4@7') >>> [str(p) for p in a()] ['E-3', 'G3', 'B3', 'E-4', 'G4', 'B4']
PitchSieve
methods
- PitchSieve.getIntervalSequence() list[music21.interval.Interval] ¶
Return a list of Interval objects that defines the complete structure of this
music21.sieve.Sieve
.>>> a = sieve.PitchSieve('3@0') >>> a.getIntervalSequence() [<music21.interval.Interval m3>]
>>> a = sieve.PitchSieve('3@0|7@0') >>> a.sieveObject.segment() [0, 3, 6, 7, 9, 12, 14, 15, 18, 21, 24, 27, 28, 30, 33, 35, 36, 39, 42, 45, 48, 49, 51, 54, 56, 57, 60, 63, 66, 69, 70, 72, 75, 77, 78, 81, 84, 87, 90, 91, 93, 96, 98, 99] >>> a.sieveObject.period() 21 >>> a.getIntervalSequence() [<music21.interval.Interval m3>, <music21.interval.Interval m3>, <music21.interval.Interval m2>, <music21.interval.Interval M2>, <music21.interval.Interval m3>, <music21.interval.Interval M2>, <music21.interval.Interval m2>, <music21.interval.Interval m3>, <music21.interval.Interval m3>]
This is the PitchSieve for a major scale:
>>> b = sieve.PitchSieve('(-3@2 & 4) | (-3@1 & 4@1) | (3@2 & 4@2) | (-3 & 4@3)') >>> b.getIntervalSequence() [<music21.interval.Interval M2>, <music21.interval.Interval M2>, <music21.interval.Interval m2>, <music21.interval.Interval M2>, <music21.interval.Interval M2>, <music21.interval.Interval M2>, <music21.interval.Interval m2>]
PrimeSegment¶
- class music21.sieve.PrimeSegment(start, length)¶
Residual¶
- class music21.sieve.Residual(m, shift=0, neg=0, z=None)¶
object that represents a modulus and a start point each object stores a range of integers (self._z) from which sections are drawn this range of integers can be changed whenever the section os drawn
>>> residual = sieve.Residual(3, 2)
Residual
methods
- Residual.__eq__(other)¶
==, compare residual classes in terms of m and shift
- Residual.copy()¶
- Residual.period() int ¶
period is M; obvious, but nice for completeness
>>> a = sieve.Residual(3, 2) >>> a.period() 3
- Residual.represent(style=None)¶
does not show any logical operator but unary negation
- Residual.segment(n=0, z=None, segmentFormat=None)¶
get a residual subset of this modulus at this n within the integer range provided by z format can be ‘int’ or ‘bin’, for integer or binary
>>> a = sieve.Residual(3, 2) >>> a.segment(3) [2, 5, 8, 11, 14, 17, 20, 23, 26, 29, 32, 35, 38, 41, 44, 47, 50, 53, 56, 59, 62, 65, 68, 71, 74, 77, 80, 83, 86, 89, 92, 95, 98] >>> a.segment(3, range(3, 15)) [5, 8, 11, 14]
- Residual.setSegmentFormat(fmt)¶
- Residual.setZ(z)¶
z is the range of integers to use when generating a list
- Residual.setZRange(minInt, maxInt)¶
z is the range of integers to use when generating a list convenience function that fixes max
Sieve¶
- class music21.sieve.Sieve(usrStr: str | list[str], z: list[int] | None = None)¶
Create a sieve segment from a sieve logical string of any complexity.
>>> a = sieve.Sieve('3@11') >>> b = sieve.Sieve('2&4&8|5') >>> c = sieve.Sieve('(5|2)&4&8')
Sieve
methods
- Sieve.collect(n: int, zMinimum: int, length: int, segmentFormat: str, zStep: int = 100) list[int] ¶
Collect sieve segment points for the provided length and format.
>>> a = sieve.Sieve('3@11') >>> a.collect(10, 100, 10, 'int') [102, 105, 108, 111, 114, 117, 120, 123, 126, 129]
- Sieve.compress(z=None)¶
Set this sieve to its compressed state.
- Sieve.expand()¶
Set this Sieve to its expanded state.
- Sieve.period() int ¶
Return the period of the sieve.
>>> a = sieve.Sieve('3@11') >>> a.period() 3 >>> b = sieve.Sieve('2&4&8|5') >>> b.period() 40 >>> c = sieve.Sieve('(5|2)&4&8') >>> c.period() 40
Changed in v9: state is taken from the object.
- Sieve.represent(state=None, style=None)¶
style of None is use for users; adds | to single residuals style abs (absolute) does not add | tos single residual class
- Sieve.segment(state: Literal['cmp'] | Literal['exp'] | None = None, n=0, z=None, segmentFormat=None) list[int] ¶
Return a sieve segment in various formats.
>>> a = sieve.Sieve('3@11') >>> a.segment('exp') [2, 5, 8, 11, 14, 17, 20, 23, 26, 29, 32, 35, 38, 41, 44, 47, 50, 53, 56, 59, 62, 65, 68, 71, 74, 77, 80, 83, 86, 89, 92, 95, 98]
>>> c = sieve.Sieve('(5|2)&4&8') >>> c.segment('cmp', segmentFormat='wid') [8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8]
- Sieve.setSegmentFormat(fmt)¶
- Sieve.setZ(z)¶
Set the z as a list. The z is the range of integers to use when generating a sieve segment.
- Sieve.setZRange(minInt, maxInt)¶
Set the z as a min and max value. The z is the range of integers to use when generating a sieve segment.
Functions¶
- music21.sieve.discreteBinaryPad(series: Iterable[int], fixRange=None) list[int] ¶
Treat a sequence of integers as defining contiguous binary integers, where provided values are 1’s and excluded values are zero.
For instance, running [3, 10, 12] through this method gives a 1 for the first entry (signifying 3), 0s for the next six entries (signifying 4-9), a 1 (for 10), a 0 (for 11), and a 1 (for 12).
>>> sieve.discreteBinaryPad([3, 10, 12]) [1, 0, 0, 0, 0, 0, 0, 1, 0, 1]
>>> sieve.discreteBinaryPad([3, 4, 5]) [1, 1, 1]
- music21.sieve.eratosthenes(firstCandidate=2)¶
Yields the sequence of prime numbers via the Sieve of Eratosthenes. rather than creating a fixed list of a range (z) and crossing out multiples of sequential candidates, this algorithm stores primes under their next possible candidate, thus allowing the generation of primes in sequence without storing a complete range (z).
Create a dictionary. Each entry in the dictionary is a key:item pair of (key) the largest multiple of this prime so far found and (item) the prime. The dictionary only has as many entries as found primes.
If a candidate is not a key in the dictionary, it is not a multiple of any already-found prime; it is thus a prime. a new entry is added to the dictionary, with the square of the prime as the key. The square of the prime is the next possible multiple to be found.
To use this generator, create an instance and then call the .next() method on the instance.
>>> a = sieve.eratosthenes() >>> next(a) 2 >>> next(a) 3
We can also specify a starting value for the sequence, skipping over initial primes smaller than this number:
>>> a = sieve.eratosthenes(95) >>> next(a) 97 >>> next(a) 101
- music21.sieve.rabinMiller(n)¶
Returns True if an integer is likely prime or False if it is likely composite using the Rabin Miller primality test.
See also here: http://www.4dsolutions.net/ocn/numeracy2.html
>>> sieve.rabinMiller(234) False >>> sieve.rabinMiller(5) True >>> sieve.rabinMiller(4) False
>>> sieve.rabinMiller(97 * 2) False
>>> sieve.rabinMiller(6 ** 4 + 1) # prime True
>>> sieve.rabinMiller(123986234193) # divisible by 3, runs fast False
- music21.sieve.unitNormEqual(parts)¶
Given a certain number of parts, return a list unit-interval values between 0 and 1, with as many divisions as parts; 0 and 1 are always inclusive.
>>> sieve.unitNormEqual(3) [0.0, 0.5, 1]
If parts is 0 or 1, then a single entry of [0] is given:
>>> sieve.unitNormEqual(1) [0]
- music21.sieve.unitNormRange(series, fixRange=None)¶
Given a list of numbers, create a proportional spacing across the unit interval.
The first entry will always be 0 and the last 1, other entries will be spaced according to their distance between these two units. For instance, for 0, 3, 4 the middle entry will be 0.75 since 3 is 3/4 of the distance between 0 and 4:
>>> sieve.unitNormRange([0, 3, 4]) [0.0, 0.75, 1.0]
but for [1, 3, 4], it will be 0.666… because 3 is 2/3 of the distance between 1 and 4
>>> sieve.unitNormRange([1, 3, 4]) [0.0, 0.666..., 1.0]
- music21.sieve.unitNormStep(step, a=0, b=1, normalized=True)¶
Given a step size and an a/b min/max range, calculate number of parts to fill step through inclusive a,b, then return a unit interval list of values necessary to cover region.
Note that returned values are, by default, normalized within the unit interval.
>>> sieve.unitNormStep(0.5, 0, 1) [0.0, 0.5, 1]
>>> sieve.unitNormStep(0.5, -1, 1) [0.0, 0.25, 0.5, 0.75, 1]
>>> sieve.unitNormStep(0.5, -1, 1, normalized=False) [-1, -0.5, 0.0, 0.5, 1.0]
>>> post = sieve.unitNormStep(0.25, 0, 20) >>> len(post) 81 >>> post = sieve.unitNormStep(0.25, 0, 20, normalized=False) >>> len(post) 81