예제 #1
0
    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)
예제 #2
0
    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)
예제 #3
0
    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)
예제 #4
0
    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)
예제 #5
0
 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)
예제 #6
0
 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)
예제 #7
0
 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)
예제 #8
0
 def test_complex_modality(self):
     cat = syntax_from_string(r"V^D /{c} I^TD")
     self.assertIsInstance(cat, ComplexCategory)
예제 #9
0
 def test_complex_modality(self):
     cat = syntax_from_string(r"V^D /{c} I^TD")
     self.assertIsInstance(cat, ComplexCategory)
예제 #10
0
    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)