pub struct Sieve { /* private fields */ }Expand description
A parsed Xenakis sieve.
use music21_rs::Sieve;
// Every third semitone: a cycle of minor thirds.
let sieve = Sieve::parse("3@0")?;
assert_eq!(sieve.period(), 3);
assert_eq!(sieve.interval_widths()?, [3]);
// The major scale, as Xenakis would write it.
let major = Sieve::parse("(-3@2 & 4) | (-3@1 & 4@1) | (3@2 & 4@2) | (-3 & 4@3)")?;
assert_eq!(major.interval_widths()?, [2, 2, 1, 2, 2, 2, 1]);Implementations§
Source§impl Sieve
impl Sieve
Sourcepub fn parse(expression: &str) -> Result<Self>
pub fn parse(expression: &str) -> Result<Self>
Parses a sieve expression such as "3@0|4@1".
A bare modulus means a shift of zero, so "5" is "5@0". Whitespace is
ignored, {} and () both group, and & binds tighter than ^, which
binds tighter than | — matching music21, where 3@0|4@0&6@0 parses as
3@0|{4@0&6@0}.
Sourcepub fn contains(&self, z: IntegerType) -> bool
pub fn contains(&self, z: IntegerType) -> bool
Returns whether an integer is in the sieve.
Sourcepub fn period(&self) -> UnsignedIntegerType
pub fn period(&self) -> UnsignedIntegerType
Returns the period: the least common multiple of every modulus.
The sieve’s membership pattern repeats with this length.
Sourcepub fn segment(&self, low: IntegerType, high: IntegerType) -> Vec<IntegerType> ⓘ
pub fn segment(&self, low: IntegerType, high: IntegerType) -> Vec<IntegerType> ⓘ
Returns the members of the sieve in low..=high.
Sourcepub fn interval_widths(&self) -> Result<Vec<IntegerType>>
pub fn interval_widths(&self) -> Result<Vec<IntegerType>>
Returns the widths between consecutive members of one period.
This is music21’s PitchSieve.getIntervalSequence, in semitones: the
sieve is evaluated over 0..=period and the consecutive differences
taken. A sieve with fewer than two members in that window has no widths
and is an error, exactly as music21 raises for 3@1.
Sourcepub fn shifted(&self, n: IntegerType) -> Self
pub fn shifted(&self, n: IntegerType) -> Self
The same sieve with every residual’s shift moved on by n.
This is the n music21 takes beside a range when it reads a segment.
Sourcepub fn segment_binary(
&self,
low: IntegerType,
high: IntegerType,
) -> Vec<IntegerType> ⓘ
pub fn segment_binary( &self, low: IntegerType, high: IntegerType, ) -> Vec<IntegerType> ⓘ
The sieve over low..=high as ones and noughts, one per integer in
the range rather than one per member.
music21’s segmentFormat='binary'.
Sourcepub fn segment_widths(
&self,
low: IntegerType,
high: IntegerType,
) -> Vec<IntegerType> ⓘ
pub fn segment_widths( &self, low: IntegerType, high: IntegerType, ) -> Vec<IntegerType> ⓘ
The widths between consecutive members over low..=high, one shorter
than the segment itself.
music21’s segmentFormat='width'. Unlike Sieve::interval_widths
this reads whatever range it is given rather than one period, so it
says nothing about where the pattern repeats.
Sourcepub fn segment_unit(
&self,
low: IntegerType,
high: IntegerType,
) -> Vec<FloatType> ⓘ
pub fn segment_unit( &self, low: IntegerType, high: IntegerType, ) -> Vec<FloatType> ⓘ
Each member’s place in low..=high as a fraction of the way across
it, so the range’s own ends are nought and one.
music21’s segmentFormat='unit'. A range with no width answers nought
for every member, as music21 does rather than dividing by it.
Sourcepub fn collect(
&self,
n: IntegerType,
z_minimum: IntegerType,
length: usize,
) -> Result<Vec<IntegerType>>
pub fn collect( &self, n: IntegerType, z_minimum: IntegerType, length: usize, ) -> Result<Vec<IntegerType>>
The first length members at or above z_minimum, reading the sieve
shifted on by n.
music21’s collect, which walks upward a hundred integers at a time
until it has enough. The walk is bounded, so a sieve with too few
members to fill the length is an error rather than a loop that never
ends.
Sourcepub fn intersection(&self, other: &Self) -> Self
pub fn intersection(&self, other: &Self) -> Self
The members of both sieves, written the way music21 writes a combined sieve: each side in braces around the operator.
a.intersection(&b) is written {a}&{b}. Note that music21’s
a & b writes the two the other way round, {b}&{a}.
Sourcepub fn union(&self, other: &Self) -> Self
pub fn union(&self, other: &Self) -> Self
The members of either sieve. See Sieve::intersection for the
bracketing and the order.
Sourcepub fn symmetric_difference(&self, other: &Self) -> Self
pub fn symmetric_difference(&self, other: &Self) -> Self
The members of one sieve or the other but not both. See
Sieve::intersection for the bracketing and the order.
Sourcepub fn compressed(&self, low: IntegerType, high: IntegerType) -> Result<Self>
pub fn compressed(&self, low: IntegerType, high: IntegerType) -> Result<Self>
The compressed reading of the sieve: a union of residual classes with
the same members, which is music21’s cmp state.
A sieve written with nothing but & and | is compressed by
intersection: each run of & becomes the one class its residuals
meet in, whatever the range. Anything written with a group, a ^ or
a complemented group is compressed from its members in low..=high
instead, by finding for each member in turn the smallest modulus
whose class holds nothing the sieve does not, so that reading depends
on the range it was taken over.
It is an error where there is no such reading: a complemented class intersected with another, classes that never meet, or fewer than two members in the range.
use music21_rs::Sieve;
assert_eq!(Sieve::parse("2&4&8|5")?.compressed(0, 99)?.to_string(), "8@0|5@0");
assert_eq!(Sieve::parse("(5|2)&4&8")?.compressed(0, 99)?.to_string(), "8@0");
assert_eq!(
Sieve::parse("3@0^4@0")?.compressed(0, 99)?.to_string(),
"6@3|12@4|12@6|12@8"
);Source§impl Sieve
impl Sieve
Sourcepub fn from_segment(
members: &[IntegerType],
range: Option<(IntegerType, IntegerType)>,
) -> Result<Self>
pub fn from_segment( members: &[IntegerType], range: Option<(IntegerType, IntegerType)>, ) -> Result<Self>
The sieve that is these integers, as music21 builds one from a list:
each run of them a residual class, found smallest modulus first, over
range or else from the least of them to the greatest.
use music21_rs::Sieve;
assert_eq!(Sieve::from_segment(&[2, 4, 6, 8], None)?.to_string(), "2@0");
assert_eq!(
Sieve::from_segment(&[2, 4, 6, 8], Some((0, 19)))?.to_string(),
"12@8|14@6|16@4|18@2"
);§Errors
Fewer than two distinct integers, or one outside range.
Trait Implementations§
Source§impl Display for Sieve
Writes the sieve as music21 writes it: the expression it was given, with
each residual normalized to modulus@shift and the groups it was written
with kept.
impl Display for Sieve
Writes the sieve as music21 writes it: the expression it was given, with
each residual normalized to modulus@shift and the groups it was written
with kept.
use music21_rs::Sieve;
assert_eq!(Sieve::parse("3@11")?.to_string(), "3@2");
assert_eq!(Sieve::parse("(5|2)&4&8")?.to_string(), "{5@0|2@0}&4@0&8@0");impl Eq for Sieve
impl StructuralPartialEq for Sieve
Auto Trait Implementations§
impl Freeze for Sieve
impl RefUnwindSafe for Sieve
impl Send for Sieve
impl Sync for Sieve
impl Unpin for Sieve
impl UnsafeUnpin for Sieve
impl UnwindSafe for Sieve
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more