def test_complex(self): cat = syntax_from_string("V^D / I^T") self.assertIsInstance(cat, ComplexCategory) cat = syntax_from_string("II^D / I^TD") self.assertIsInstance(cat, ComplexCategory) cat = syntax_from_string(r"bVI^T \ I^S") self.assertIsInstance(cat, ComplexCategory)
def test_half_atomic(self): cat = syntax_from_string("I^T") self.assertIsInstance(cat, AtomicCategory) cat = syntax_from_string("II^D") self.assertIsInstance(cat, AtomicCategory) cat = syntax_from_string("bV^S") self.assertIsInstance(cat, AtomicCategory)
def test_full_atomic(self): cat = syntax_from_string("I^T-II^T") self.assertIsInstance(cat, AtomicCategory) cat = syntax_from_string("II^D - V^T") self.assertIsInstance(cat, AtomicCategory) cat = syntax_from_string("VII^S - I^T") self.assertIsInstance(cat, AtomicCategory)
def test_complex(self): cat = syntax_from_string("V^D / I^T") self.assertIsInstance(cat, ComplexCategory) cat = syntax_from_string("II^D / I^TD") self.assertIsInstance(cat, ComplexCategory) cat = syntax_from_string(r"bVI^T \ I^S") self.assertIsInstance(cat, ComplexCategory)
def test_full_atomic(self): cat = syntax_from_string("I^T-II^T") self.assertIsInstance(cat, AtomicCategory) cat = syntax_from_string("II^D - V^T") self.assertIsInstance(cat, AtomicCategory) cat = syntax_from_string("VII^S - I^T") self.assertIsInstance(cat, AtomicCategory)
def test_half_atomic(self): cat = syntax_from_string("I^T") self.assertIsInstance(cat, AtomicCategory) cat = syntax_from_string("II^D") self.assertIsInstance(cat, AtomicCategory) cat = syntax_from_string("bV^S") self.assertIsInstance(cat, AtomicCategory)
def generate(self, logger=None, max_depth=None): """ Generate a chord sequence from the model. """ if logger is None: logger = create_dummy_logger() def _generate(parent, depth=0, pitch=0): # Transform the parent category so it's relative to itself # All generated categories will be relative to this, # so we need to make the parent self-relative at the # start of each recursion parent_rep = model_category_repr(parent) parent_pitch = (pitch + base_pitch(parent)) % 12 logger.debug("%sGenerating from parent: %s" % (" "*depth,parent_rep)) if max_depth is not None and depth >= max_depth and \ len(self._lexical_dist[parent_rep].samples()) != 0: # Don't go any deeper than this if we can stop here # Only possible if the parent has generated a leaf before exp = 'leaf' logger.debug("%sForcing leaf" % (" "*depth)) else: # Otherwise freely generate an expansion type exp = generate_from_prob_dist(self._expansion_type_dist[parent_rep]) logger.debug("%sExpansion: %s" % (" "*depth, exp)) exp_parent = (exp,parent_rep) if exp == 'leaf': # Generate a leaf node (word) word = generate_from_prob_dist(self._lexical_dist[parent_rep]) logger.debug("%sWord: %s, pitch: %d" % (" "*depth, word, parent_pitch)) chord = Chord.from_name(word) chord.root = (chord.root + parent_pitch) % 12 return [chord] else: # First generate a head node head = generate_from_prob_dist(self._head_expansion_dist[exp_parent]) logger.debug("%sHead: %s" % (" "*depth, head)) # Continue to expand this recursively to a word sequence head_generated = _generate(head, depth=depth+1, \ pitch=parent_pitch) head_exp_parent = (head,exp,parent_rep) # Now generate a non-head node non_head = generate_from_prob_dist( self._non_head_expansion_dist[head_exp_parent]) logger.debug("%sNon-head: %s" % (" "*depth, non_head)) # Continue to expand this too non_head_generated = _generate(non_head, depth=depth+1, \ pitch=parent_pitch) return non_head_generated + head_generated # Choose a start node # Build a I^T-I^T as the root root = syntax_from_string("I^T-I^T") logger.debug("Root: %s" % root) return _generate(root)
def test_complex_modality(self): cat = syntax_from_string(r"V^D /{c} I^TD") self.assertIsInstance(cat, ComplexCategory)
def test_complex_modality(self): cat = syntax_from_string(r"V^D /{c} I^TD") self.assertIsInstance(cat, ComplexCategory)
def generate(self, logger=None, max_depth=None): """ Generate a chord sequence from the model. """ if logger is None: logger = create_dummy_logger() def _generate(parent, depth=0, pitch=0): # Transform the parent category so it's relative to itself # All generated categories will be relative to this, # so we need to make the parent self-relative at the # start of each recursion parent_rep = model_category_repr(parent) parent_pitch = (pitch + base_pitch(parent)) % 12 logger.debug("%sGenerating from parent: %s" % (" " * depth, parent_rep)) if max_depth is not None and depth >= max_depth and \ len(self._lexical_dist[parent_rep].samples()) != 0: # Don't go any deeper than this if we can stop here # Only possible if the parent has generated a leaf before exp = 'leaf' logger.debug("%sForcing leaf" % (" " * depth)) else: # Otherwise freely generate an expansion type exp = generate_from_prob_dist( self._expansion_type_dist[parent_rep]) logger.debug("%sExpansion: %s" % (" " * depth, exp)) exp_parent = (exp, parent_rep) if exp == 'leaf': # Generate a leaf node (word) word = generate_from_prob_dist(self._lexical_dist[parent_rep]) logger.debug("%sWord: %s, pitch: %d" % (" " * depth, word, parent_pitch)) chord = Chord.from_name(word) chord.root = (chord.root + parent_pitch) % 12 return [chord] else: # First generate a head node head = generate_from_prob_dist( self._head_expansion_dist[exp_parent]) logger.debug("%sHead: %s" % (" " * depth, head)) # Continue to expand this recursively to a word sequence head_generated = _generate(head, depth=depth+1, \ pitch=parent_pitch) head_exp_parent = (head, exp, parent_rep) # Now generate a non-head node non_head = generate_from_prob_dist( self._non_head_expansion_dist[head_exp_parent]) logger.debug("%sNon-head: %s" % (" " * depth, non_head)) # Continue to expand this too non_head_generated = _generate(non_head, depth=depth+1, \ pitch=parent_pitch) return non_head_generated + head_generated # Choose a start node # Build a I^T-I^T as the root root = syntax_from_string("I^T-I^T") logger.debug("Root: %s" % root) return _generate(root)