def is_pitch_class_unique(self): r'''Is true when pitch set is pitch-class-unique. Otherwise false. .. container:: example >>> set_ = abjad.PitchSet( ... items=[-2, -1.5, 6, 7, -1.5, 7], ... item_class=abjad.NumberedPitch, ... ) >>> set_.is_pitch_class_unique True .. container:: example >>> set_ = abjad.PitchSet( ... items=[-2, -1.5, 6, 7, 10.5, 7], ... item_class=abjad.NumberedPitch, ... ) >>> set_.is_pitch_class_unique False Returns true or false. ''' from abjad.tools import pitchtools numbered_pitch_class_set = pitchtools.PitchClassSet( self, item_class=pitchtools.NumberedPitchClass) return len(self) == len(numbered_pitch_class_set)
def duplicate_pitch_classes(self): r'''Gets duplicate pitch-classes in pitch set. .. container:: example >>> set_ = abjad.PitchSet( ... items=[-2, -1.5, 6, 7, -1.5, 7], ... item_class=abjad.NumberedPitch, ... ) >>> set_.duplicate_pitch_classes PitchClassSet([]) >>> set_ = abjad.PitchSet( ... items=[-2, -1.5, 6, 7, 10.5, 7], ... item_class=abjad.NumberedPitch, ... ) >>> set_.duplicate_pitch_classes PitchClassSet([10.5]) Returns pitch-class set. ''' from abjad.tools import pitchtools pitch_classes = [] duplicate_pitch_classes = [] for pitch in self: pitch_class = pitchtools.NumberedPitchClass(pitch) if pitch_class in pitch_classes: duplicate_pitch_classes.append(pitch_class) pitch_classes.append(pitch_class) return pitchtools.PitchClassSet( duplicate_pitch_classes, item_class=pitchtools.NumberedPitchClass, )
def is_pitch_class_unique(self): r'''Is true when pitch set is pitch-class-unique. Otherwise false. Returns true or false. ''' from abjad.tools import pitchtools numbered_pitch_class_set = pitchtools.PitchClassSet( self, item_class=pitchtools.NumberedPitchClass) return len(self) == len(numbered_pitch_class_set)
def inventory_aggregate_subsets(): '''Inventory aggregate subsets: :: >>> U_star = pitchtools.inventory_aggregate_subsets() >>> len(U_star) 4096 >>> for pcset in U_star[:20]: ... pcset PitchClassSet([]) PitchClassSet([0]) PitchClassSet([1]) PitchClassSet([0, 1]) PitchClassSet([2]) PitchClassSet([0, 2]) PitchClassSet([1, 2]) PitchClassSet([0, 1, 2]) PitchClassSet([3]) PitchClassSet([0, 3]) PitchClassSet([1, 3]) PitchClassSet([0, 1, 3]) PitchClassSet([2, 3]) PitchClassSet([0, 2, 3]) PitchClassSet([1, 2, 3]) PitchClassSet([0, 1, 2, 3]) PitchClassSet([4]) PitchClassSet([0, 4]) PitchClassSet([1, 4]) PitchClassSet([0, 1, 4]) There are 4096 subsets of the aggregate. This is ``U*`` in [Morris 1987]. Returns list of numbered pitch-class sets. ''' from abjad.tools import pitchtools def _helper(binary_string): result = zip(binary_string, range(len(binary_string))) result = [x[1] for x in result if x[0] == '1'] return result result = [] for x in range(4096): subset = ''.join( list(reversed(mathtools.integer_to_binary_string(x).zfill(12)))) subset = _helper(subset) subset = pitchtools.PitchClassSet( subset, item_class=pitchtools.NumberedPitchClass, ) result.append(subset) return result
def _analyze_incomplete_chord(expr): from abjad.tools import tonalanalysistools pitches = pitchtools.PitchSegment.from_selection(expr) npcset = pitchtools.PitchClassSet( pitches, item_class=pitchtools.NamedPitchClass) dicv = pitchtools.IntervalClassVector( items=npcset, item_class=pitchtools.NamedInversionEquivalentIntervalClass, ) # TODO: eliminate code duplication # if dicv == TonalAnalysisAgent._make_dicv('c', 'ef'): model_npcs = ['c', 'ef'] quality, extent = 'minor', 'triad' elif dicv == TonalAnalysisAgent._make_dicv('c', 'e'): model_npcs = ['c', 'e'] quality, extent = 'major', 'triad' elif dicv == TonalAnalysisAgent._make_dicv('c', 'ef', 'bff'): model_npcs = ['c', 'ef', 'bff'] quality, extent = 'diminished', 'seventh' elif dicv == TonalAnalysisAgent._make_dicv('c', 'ef', 'bf'): model_npcs = ['c', 'ef', 'bf'] quality, extent = 'minor', 'seventh' elif dicv == TonalAnalysisAgent._make_dicv('c', 'e', 'bf'): model_npcs = ['c', 'e', 'bf'] quality, extent = 'dominant', 'seventh' elif dicv == TonalAnalysisAgent._make_dicv('c', 'e', 'b'): model_npcs = ['c', 'e', 'b'] quality, extent = 'major', 'seventh' else: message = 'can not identify incomplete tertian chord.' raise ValueError(message) bass = min(pitches).named_pitch_class try: npcseg = npcset.order_by( pitchtools.PitchClassSegment( model_npcs, item_class=pitchtools.NamedPitchClass, )) except ValueError: message = 'can not identify incomplete tertian chord.' raise ValueError(message) inversion = npcseg.index(bass) root = npcseg[0] return tonalanalysistools.RootedChordClass( root, quality, extent, inversion, )
def duplicate_pitch_classes(self): r'''Duplicate pitch-classes in pitch set. Returns pitch-class set. ''' from abjad.tools import pitchtools pitch_classes = [] duplicate_pitch_classes = [] for pitch in self: pitch_class = pitchtools.NumberedPitchClass(pitch) if pitch_class in pitch_classes: duplicate_pitch_classes.append(pitch_class) pitch_classes.append(pitch_class) return pitchtools.PitchClassSet( duplicate_pitch_classes, item_class=pitchtools.NumberedPitchClass, )
def has_duplicates(self): r'''True if segment contains duplicate items: :: >>> pitch_class_segment = pitchtools.PitchClassSegment( ... items=[-2, -1.5, 6, 7, -1.5, 7], ... ) >>> pitch_class_segment.has_duplicates True :: >>> pitch_class_segment = pitchtools.PitchClassSegment( ... items="c d e f g a b", ... ) >>> pitch_class_segment.has_duplicates False Returns true or false. ''' from abjad.tools import pitchtools return len(pitchtools.PitchClassSet(self)) < len(self)
def _analyze_chord(expr): from abjad.tools import tonalanalysistools pitches = pitchtools.PitchSegment.from_selection(expr) npcset = pitchtools.PitchClassSet( pitches, item_class=pitchtools.NamedPitchClass, ) ordered_npcs = [] letters = ('c', 'e', 'g', 'b', 'd', 'f', 'a') for letter in letters: for npc in npcset: if npc.diatonic_pitch_class_name == letter: ordered_npcs.append(npc) ordered_npcs = pitchtools.PitchClassSegment( ordered_npcs, item_class=pitchtools.NamedPitchClass) for x in range(len(ordered_npcs)): ordered_npcs = ordered_npcs.rotate(1) segment = \ pitchtools.IntervalClassSegment( items=mathtools.difference_series(ordered_npcs), item_class=pitchtools.NamedInversionEquivalentIntervalClass, ) if segment.is_tertian: break else: return None root = ordered_npcs[0] class_ = tonalanalysistools.RootlessChordClass rootless_chord_class = class_.from_interval_class_segment(segment) bass = min(pitches).named_pitch_class inversion = ordered_npcs.index(bass) return tonalanalysistools.RootedChordClass( root, rootless_chord_class.quality_string, rootless_chord_class.extent, inversion, )
def yield_all_pitch_class_sets(): '''Yields all pitch-class sets. .. container:: example :: >>> all_pitch_class_sets = pitchtools.yield_all_pitch_class_sets() >>> len(all_pitch_class_sets) 4096 :: >>> for pitch_class_set in all_pitch_class_sets[:20]: ... pitch_class_set PitchClassSet([]) PitchClassSet([0]) PitchClassSet([1]) PitchClassSet([0, 1]) PitchClassSet([2]) PitchClassSet([0, 2]) PitchClassSet([1, 2]) PitchClassSet([0, 1, 2]) PitchClassSet([3]) PitchClassSet([0, 3]) PitchClassSet([1, 3]) PitchClassSet([0, 1, 3]) PitchClassSet([2, 3]) PitchClassSet([0, 2, 3]) PitchClassSet([1, 2, 3]) PitchClassSet([0, 1, 2, 3]) PitchClassSet([4]) PitchClassSet([0, 4]) PitchClassSet([1, 4]) PitchClassSet([0, 1, 4]) There are 4096 pitch-class sets. This is ``U*`` in [Morris 1987]. Returns list of numbered pitch-class sets. ''' from abjad.tools import pitchtools def _helper(binary_string): result = zip(binary_string, range(len(binary_string))) result = [x[1] for x in result if x[0] == '1'] return result result = [] for x in range(4096): string = mathtools.integer_to_binary_string(x).zfill(12) subset = ''.join(list(reversed(string))) subset = _helper(subset) subset = pitchtools.PitchClassSet( subset, item_class=pitchtools.NumberedPitchClass, ) result.append(subset) return result