.. _moduleIntervalNetwork:

music21.intervalNetwork
=======================

.. WARNING: DO NOT EDIT THIS FILE: AUTOMATICALLY GENERATED. Edit the .py file directly

.. module:: music21.intervalNetwork

An BoundIntervalNetwork defines a scale or harmonic unit as a (weighted)
digraph, or directed graph, where pitches are nodes and intervals are
edges. Nodes, however, are not stored; instead, an ordered list of edges
(Intervals) is provided as an archetype of adjacent nodes.

IntervalNetworks are unlike conventional graphs in that each graph must
define a low and high terminus. These points are used to create a cyclic
graph and are treated as point of cyclical overlap.

BoundIntervalNetwork permits the definition of conventional octave repeating
scales or harmonies (abstract chords), non-octave repeating scales and
chords, and ordered interval sequences that might move in multiple
directions.

A scale or harmony may be composed of one or more BoundIntervalNetwork objects.

Both nodes and edges can be weighted to suggest tonics, dominants,
finals, or other attributes of the network.




BoundIntervalNetwork
--------------------

Inherits from: :class:`~music21.intervalNetwork.IntervalNetwork`

.. class:: BoundIntervalNetwork(edgeList=None, octaveDuplicating=False, deterministic=True, pitchSimplification='maxAccidental')


    A graph of undefined Pitch nodes connected by a defined,
    ordered list of :class:`~music21.interval.Interval` objects as edges.


    An `octaveDuplicating` boolean, if defined, can be used
    to optimize pitch realization routines.


    The `deterministic` boolean, if defined, can be used to declare that there
    is no probabilistic or multi-pathway segments of this network.


    The `pitchSimplification` method specifies how to simplify the pitches
    if they spiral out into double and triple sharps, etc.  The default is
    'maxAccidental' which specifies that each note can have at most one
    accidental; double-flats and sharps are not allowed.  The other choices
    are 'simplifyEnharmonic' (which also converts C-, F-, B#, and E# to
    B, E, C, and F respectively, see :meth:`~music21.pitch.Pitch.simplifyEnharmonic`),
    'mostCommon' (which adds to simplifyEnharmonic the requirement that the
    most common accidential forms be used, so A# becomes B-, G- becomes
    F#, etc. the only ambiguity allowed is that both G# and A- are acceptable),
    and None (or 'none') which does not do any simplification.



    **BoundIntervalNetwork** **attributes**

        Attributes without Documentation: `pitchSimplification`, `octaveDuplicating`, `deterministic`

    **BoundIntervalNetwork** **properties**

        .. attribute:: degreeMax

            Return the largest degree value.



            >>> from music21 import *
            >>> edgeList = ['M2', 'M2', 'm2', 'M2', 'M2', 'M2', 'm2']
            >>> net = intervalNetwork.BoundIntervalNetwork()
            >>> net.fillBiDirectedEdges(edgeList)
            >>> net.degreeMax
            8



        .. attribute:: degreeMaxUnique

            Return the largest degree value that represents a pitch level that is not a terminus of the scale.



            >>> from music21 import *
            >>> edgeList = ['M2', 'M2', 'm2', 'M2', 'M2', 'M2', 'm2']
            >>> net = intervalNetwork.BoundIntervalNetwork()
            >>> net.fillBiDirectedEdges(edgeList)
            >>> net.degreeMaxUnique
            7



        .. attribute:: degreeMin

            Return the lowest degree value.



            >>> from music21 import *
            >>> edgeList = ['M2', 'M2', 'm2', 'M2', 'M2', 'M2', 'm2']
            >>> net = intervalNetwork.BoundIntervalNetwork()
            >>> net.fillBiDirectedEdges(edgeList)
            >>> net.degreeMin
            1



        .. attribute:: networkxGraph


            Return a networks Graph object representing a realized version of this BoundIntervalNetwork



        .. attribute:: terminusHighNodes

            Return a list of last Nodes, or Nodes that contain "end". Return the coordinates of the last Node. Nodes are not stored, but are encoded as pairs, index values, to stored edges. Indices are either integers or the



            >>> from music21 import *
            >>> edgeList = ['M2', 'M2', 'm2', 'M2', 'M2', 'M2', 'm2']
            >>> net = intervalNetwork.BoundIntervalNetwork()
            >>> net.fillBiDirectedEdges(edgeList)
            >>> net.terminusHighNodes[0]
            <music21.intervalNetwork.Node id='terminusHigh'>



        .. attribute:: terminusLowNodes

            Return a list of first Nodes, or Nodes that contain "terminusLow". Nodes are not stored, but are encoded as pairs, index values, to stored edges. Indices are either integers or the strings



            >>> from music21 import *
            >>> edgeList = ['M2', 'M2', 'm2', 'M2', 'M2', 'M2', 'm2']
            >>> net = intervalNetwork.BoundIntervalNetwork()
            >>> net.fillBiDirectedEdges(edgeList)
            >>> net.terminusLowNodes[0]
            <music21.intervalNetwork.Node id='terminusLow'>



    **BoundIntervalNetwork** **methods**

        .. method:: clear()

            Remove and reset all Nodes and Edges.



        .. method:: fillArbitrary(nodes, edges)

            Fill any arbitrary network given node and edge definitions.

            Nodes must be defined by a dictionary of id and degree values. There must be a terminusLow and terminusHigh id as string::

                nodes = ({'id':'terminusLow', 'degree':1},
                         {'id':0, 'degree':2},
                         {'id':'terminusHigh', 'degree':3},
                        )

            Edges must be defined by a dictionary of :class:`~music21.interval.Interval` strings and connections. Id values will be automatically assigned. Each connection must define direction and pairs of valid node ids::

                edges = ({'interval':'m2', connections:(
                                ['terminusLow', 0, 'bi'],
                            )},
                        {'interval':'M3', connections:(
                                [0, 'terminusHigh', 'bi'],
                            )},
                        )




            >>> from music21 import *
            >>> nodes = ({'id':'terminusLow', 'degree':1}, {'id':0, 'degree':2}, {'id':'terminusHigh', 'degree':3})
            >>> edges = ({'interval':'m2', 'connections':(['terminusLow', 0, 'bi'],)},{'interval':'M3', 'connections':([0, 'terminusHigh', 'bi'],)},)
            ⁠ 
            >>> net = intervalNetwork.BoundIntervalNetwork()
            >>> net.fillArbitrary(nodes, edges)
            >>> net.realizePitch('c4', 1)
            [C4, D-4, F4]



        .. method:: fillBiDirectedEdges(edgeList)


            Given an ordered list of bi-directed edges given as :class:`~music21.interval.Interval`
            specifications, create and define appropriate Nodes. This
            assumes that all edges are bidirected and all all edges are in order.




            >>> from music21 import *
            >>> edgeList = ['M2', 'M2', 'm2', 'M2', 'M2', 'M2', 'm2']
            >>> net = intervalNetwork.BoundIntervalNetwork()
            >>> net.fillBiDirectedEdges(edgeList)
            >>> net.realizePitch('g4')
            [G4, A4, B4, C5, D5, E5, F#5, G5]
            >>> net.degreeMin, net.degreeMax
            (1, 8)
            ⁠ 
            >>> # using another fill method creates a new network
            >>> net.fillBiDirectedEdges(['M3', 'M3', 'M3'])
            >>> net.realizePitch('g4')
            [G4, B4, D#5, G5]
            >>> net.degreeMin, net.degreeMax
            (1, 4)



            >>> net.fillBiDirectedEdges([interval.Interval('M3'), interval.Interval('M3'), interval.Interval('M3')])
            >>> net.realizePitch('c2')
            [C2, E2, G#2, B#2]



        .. method:: fillDirectedEdges(ascendingEdgeList, descendingEdgeList)


            Given two lists of edges, one for ascending :class:`~music21.interval.Interval` objects and
            another for  descending, construct appropriate Nodes and Edges.

            Note that the descending :class:`~music21.interval.Interval` ojbects should be given in ascending form.



        .. method:: fillMelodicMinor()

            A convenience routine for testing a complex, bi-directional scale.



            >>> from music21 import *
            >>> net = intervalNetwork.BoundIntervalNetwork()
            >>> net.fillMelodicMinor()
            >>> net.realizePitch('c4')
            [C4, D4, E-4, F4, G4, A4, B4, C5]




        .. method:: find(pitchTarget, resultsReturned=4, comparisonAttribute='pitchClass', alteredDegrees={})

            Given a collection of pitches, test all transpositions of a realized version of this network, and return the number of matches in each for each pitch assigned to the first node.



            >>> from music21 import *
            >>> edgeList = ['M2', 'M2', 'm2', 'M2', 'M2', 'M2', 'm2']
            >>> net = intervalNetwork.BoundIntervalNetwork(edgeList)
            >>> # a network built on G or D as
            >>> net.find(['g', 'a', 'b', 'd', 'f#'])
            [(5, G), (5, D), (4, A), (4, C)]
            ⁠ 
            >>> net.find(['g', 'a', 'b', 'c', 'd', 'e', 'f#'])
            [(7, G), (6, D), (6, C), (5, A)]




        .. method:: findMissing(pitchReference, nodeId, pitchTarget, comparisonAttribute='pitchClass', minPitch=None, maxPitch=None, direction='ascending', alteredDegrees={})

            Find all pitches in the realized scale that are not in the pitch target network based on the comparison attribute.



            >>> from music21 import *
            >>> edgeList = ['M2', 'M2', 'm2', 'M2', 'M2', 'M2', 'm2']
            >>> net = intervalNetwork.BoundIntervalNetwork(edgeList)
            >>> net.realizePitch('G3')
            [G3, A3, B3, C4, D4, E4, F#4, G4]
            >>> net.findMissing('g', 1, ['g', 'a', 'b', 'd', 'f#'])
            [C5, E5]



        .. method:: getNeighborNodeIds(pitchReference, nodeName, pitchTarget, direction='ascending', alteredDegrees={})

            Given a reference pitch assigned to a node id, determine the node ids that neighbor this pitch.

            Returns None if an exact match.



            >>> from music21 import *
            >>> edgeList = ['M2', 'M2', 'm2', 'M2', 'M2', 'M2', 'm2']
            >>> net = intervalNetwork.BoundIntervalNetwork(edgeList)
            >>> net.getNeighborNodeIds('c4', 1, 'b-')
            (4, 5)
            >>> net.getNeighborNodeIds('c4', 1, 'b')
            (5, 'terminusHigh')



        .. method:: getPitchFromNodeDegree(pitchReference, nodeName, nodeDegreeTarget, direction='ascending', minPitch=None, maxPitch=None, alteredDegrees={}, equateTermini=True)

            Given a reference pitch assigned to node id, determine the pitch for the the target node degree.



            >>> from music21 import *
            >>> edgeList = ['M2', 'M2', 'm2', 'M2', 'M2', 'M2', 'm2']
            >>> net = intervalNetwork.BoundIntervalNetwork(edgeList)
            >>> net.realizePitch(pitch.Pitch('e-2'))
            [E-2, F2, G2, A-2, B-2, C3, D3, E-3]
            >>> net.getPitchFromNodeDegree('e4', 1, 1)
            E4
            >>> net.getPitchFromNodeDegree('e4', 1, 7) # seventh scale degree
            D#5
            >>> net.getPitchFromNodeDegree('e4', 1, 8)
            E4
            >>> net.getPitchFromNodeDegree('e4', 1, 9)
            F#4
            >>> net.getPitchFromNodeDegree('e4', 1, 3, minPitch='c2', maxPitch='c3')
            G#2


            This will always get the lowest pitch:



            >>> net.getPitchFromNodeDegree('e4', 1, 3, minPitch='c2', maxPitch='c10')
            G#2
            ⁠ 
            >>> net.fillMelodicMinor()
            >>> net.getPitchFromNodeDegree('c', 1, 5)
            G4
            >>> net.getPitchFromNodeDegree('c', 1, 6, 'ascending')
            A4
            >>> net.getPitchFromNodeDegree('c', 1, 6, 'descending')
            A-4




        .. method:: getRelativeNodeDegree(pitchReference, nodeName, pitchTarget, comparisonAttribute='ps', direction='ascending', alteredDegrees={})

            Given a reference pitch assigned to node id, determine the relative node id of pitchTarget, even if displaced over multiple octaves

            Need flags for pitch class and enharmonic comparison.



            >>> from music21 import *
            >>> edgeList = ['M2', 'M2', 'm2', 'M2', 'M2', 'M2', 'm2']
            >>> net = intervalNetwork.BoundIntervalNetwork(edgeList)
            >>> net.realizePitch(pitch.Pitch('e-2'))
            [E-2, F2, G2, A-2, B-2, C3, D3, E-3]
            ⁠ 
            >>> net.getRelativeNodeDegree('e-2', 1, 'd3') # if e- is tonic, what is d3
            7
            >>> net.getRelativeNodeDegree('e3', 1, 'd5') == None
            True
            >>> net.getRelativeNodeDegree('e-3', 1, 'b-3')
            5



            >>> net.getRelativeNodeDegree('e-3', 1, 'e-5')
            1
            >>> net.getRelativeNodeDegree('e-2', 1, 'f3')
            2
            >>> net.getRelativeNodeDegree('e-3', 1, 'b6') == None
            True
            ⁠ 
            >>> net.getRelativeNodeDegree('e-3', 1, 'e-2')
            1
            >>> net.getRelativeNodeDegree('e-3', 1, 'd3')
            7
            >>> net.getRelativeNodeDegree('e-3', 1, 'e-3')
            1
            >>> net.getRelativeNodeDegree('e-3', 1, 'b-1')
            5




            >>> edgeList = ['p4', 'p4', 'p4'] # a non octave-repeating scale
            >>> net = intervalNetwork.BoundIntervalNetwork(edgeList)
            >>> net.realizePitch('f2')
            [F2, B-2, E-3, A-3]
            >>> net.realizePitch('f2', 1, 'f2', 'f6')
            [F2, B-2, E-3, A-3, D-4, G-4, C-5, F-5, A5, D6]
            ⁠ 
            >>> net.getRelativeNodeDegree('f2', 1, 'a-3') # could be 4 or 1
            1
            >>> net.getRelativeNodeDegree('f2', 1, 'd-4') # 2 is correct
            2
            >>> net.getRelativeNodeDegree('f2', 1, 'g-4') # 3 is correct
            3
            >>> net.getRelativeNodeDegree('f2', 1, 'c-5') # could be 4 or 1
            1
            >>> net.getRelativeNodeDegree('f2', 1, 'e--6') # could be 4 or 1
            1



            >>> net.realizePitch('f6', 1, 'f2', 'f6')
            [G#2, C#3, F#3, B3, E4, A4, D5, G5, C6, F6]
            ⁠ 
            >>> net.getRelativeNodeDegree('f6', 1, 'd5')
            1
            >>> net.getRelativeNodeDegree('f6', 1, 'g5')
            2
            >>> net.getRelativeNodeDegree('f6', 1, 'a4')
            3
            >>> net.getRelativeNodeDegree('f6', 1, 'e4')
            2
            >>> net.getRelativeNodeDegree('f6', 1, 'b3')
            1




        .. method:: getRelativeNodeId(pitchReference, nodeName, pitchTarget, comparisonAttribute='ps', direction='ascending', alteredDegrees={})

            Given a reference pitch assigned to node id, determine the relative node id of pitchTarget, even if displaced over multiple octaves

            The `nodeName` parameter may be a :class:`~music21.intervalNetwork.Node` object, a node degree, a terminus string, or a None (indicating 'terminusLow').

            Returns None if no match.

            If `getNeighbor` is True, or direction, the nearest node will be returned.

            If more than one node defines the same pitch, Node weights are used to select a single node.



            >>> from music21 import *
            >>> edgeList = ['M2', 'M2', 'm2', 'M2', 'M2', 'M2', 'm2']
            >>> net = intervalNetwork.BoundIntervalNetwork(edgeList)
            >>> net.getRelativeNodeId('a', 1, 'a4')
            'terminusLow'
            >>> net.getRelativeNodeId('a', 1, 'b-4') == None
            True



        .. method:: match(pitchReference, nodeId, pitchTarget, comparisonAttribute='pitchClass', alteredDegrees={})

            Given one or more pitches in `pitchTarget`, return a list of matched pitches, and unmatched pitches.



            >>> from music21 import *
            >>> edgeList = ['M2', 'M2', 'm2', 'M2', 'M2', 'M2', 'm2']
            >>> net = intervalNetwork.BoundIntervalNetwork(edgeList)
            >>> net.realizePitch('e-2')
            [E-2, F2, G2, A-2, B-2, C3, D3, E-3]
            ⁠ 
            >>> net.match('e-2', 1, 'c3') # if e- is tonic, is 'c3' in the scale?
            ([C3], [])



            >>> net.match('e-2', 1, 'd3')
            ([D3], [])
            ⁠ 
            >>> net.match('e-2', 1, 'd#3')
            ([D#3], [])



            >>> net.match('e-2', 1, 'e3')
            ([], [E3])
            ⁠ 
            >>> pitchTarget = [pitch.Pitch('b-2'), pitch.Pitch('b2'), pitch.Pitch('c3')]
            >>> net.match('e-2', 1, pitchTarget)
            ([B-2, C3], [B2])



            >>> pitchTarget = ['b-2', 'b2', 'c3', 'e-3', 'e#3', 'f2', 'e--2']
            >>> net.match('e-2', 1, pitchTarget)
            ([B-2, C3, E-3, E#3, F2, E--2], [B2])




        .. method:: nextPitch(pitchReference, nodeName, pitchOrigin, direction='ascending', stepSize=1, alteredDegrees={}, getNeighbor=True)

            Given a pitchReference, nodeName, and a pitch origin, return the next pitch.

            The `nodeName` parameter may be a :class:`~music21.intervalNetwork.Node` object, a node degree, a terminus string, or a None (indicating 'terminusLow').

            The `stepSize` parameter can be configured to permit different sized steps in the specified direction.



            >>> from music21 import *
            >>> edgeList = ['M2', 'M2', 'm2', 'M2', 'M2', 'M2', 'm2']
            >>> net = intervalNetwork.BoundIntervalNetwork()
            >>> net.fillBiDirectedEdges(edgeList)
            >>> net.nextPitch('g', 1, 'f#5', 'ascending')
            G5
            >>> net.nextPitch('g', 1, 'f#5', 'descending')
            E5
            >>> net.nextPitch('g', 1, 'f#5', 'ascending', 2) # two steps
            A5
            >>> alteredDegrees = {2:{'direction':'bi', 'interval':interval.Interval('-a1')}}
            >>> net.nextPitch('g', 1, 'g2', 'ascending', alteredDegrees=alteredDegrees)
            A-2
            >>> net.nextPitch('g', 1, 'a-2', 'ascending', alteredDegrees=alteredDegrees)
            B2



        .. method:: plot(pitchObj=None, nodeId=None, minPitch=None, maxPitch=None, *args, **keywords)

            Given a method and keyword configuration arguments, create and display a plot.



        .. method:: realize(pitchReference, nodeId=None, minPitch=None, maxPitch=None, direction='ascending', alteredDegrees={}, reverse=False)


            Realize the nodes of this network based on a pitch assigned to a
            valid `nodeId`, where `nodeId` can be specified by integer
            (starting from 1) or key (a tuple of origin, destination keys).

            Without a min or max pitch, the given pitch reference is assigned
            to the designated node, and then both ascends to the terminus and
            descends to the terminus.

            The `alteredDegrees` dictionary permits creating mappings between
            node degree and direction and :class:`~music21.interval.Interval`
            based transpositions.

            Returns two lists, a list of pitches, and a list of Node keys.



            >>> from music21 import *
            >>> edgeList = ['M2', 'M2', 'm2', 'M2', 'M2', 'M2', 'm2']
            >>> net = intervalNetwork.BoundIntervalNetwork()
            >>> net.fillBiDirectedEdges(edgeList)
            >>> net.realize('c2', 1, 'c2', 'c3')
            ([C2, D2, E2, F2, G2, A2, B2, C3], ['terminusLow', 0, 1, 2, 3, 4, 5, 'terminusHigh'])
            >>> alteredDegrees = {7:{'direction':'bi', 'interval':interval.Interval('-a1')}}
            >>> net.realize('c2', 1, 'c2', 'c4', alteredDegrees=alteredDegrees)
            ([C2, D2, E2, F2, G2, A2, B-2, C3, D3, E3, F3, G3, A3, B-3, C4], ['terminusLow', 0, 1, 2, 3, 4, 5, 'terminusHigh', 0, 1, 2, 3, 4, 5, 'terminusHigh'])




        .. method:: realizeIntervals(nodeId=None, minPitch=None, maxPitch=None, direction='ascending', alteredDegrees={}, reverse=False)

            Realize the sequence of intervals between the specified pitches, or the termini.



            >>> from music21 import *
            >>> edgeList = ['M2', 'M2', 'm2', 'M2', 'M2', 'M2', 'm2']
            >>> net = intervalNetwork.BoundIntervalNetwork()
            >>> net.fillBiDirectedEdges(edgeList)
            >>> net.realizeIntervals()
            [<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>]



        .. method:: realizeMinMax(pitchReference, nodeId=None, alteredDegrees={})

            Realize the min and max pitches of the scale, or the min and max values found between two termini.

            This suggests that min and max might be beyond the terminus.



            >>> from music21 import *
            >>> edgeList = ['M2', 'M2', 'm2', 'M2', 'M2', 'M2', 'm2']
            >>> net = intervalNetwork.BoundIntervalNetwork()
            >>> net.fillBiDirectedEdges(edgeList)



        .. method:: realizePitch(pitchReference, nodeId=None, minPitch=None, maxPitch=None, direction='ascending', alteredDegrees={}, reverse=False)


            Realize the native nodes of this network based on a pitch
            assigned to a valid `nodeId`, where `nodeId` can be specified by integer
            (starting from 1) or key (a tuple of origin, destination keys).

            The nodeId, when a simple, linear network, can be used as a scale degree value starting from one.



            >>> from music21 import *
            >>> edgeList = ['M2', 'M2', 'm2', 'M2', 'M2', 'M2', 'm2']
            >>> net = intervalNetwork.BoundIntervalNetwork()
            >>> net.fillBiDirectedEdges(edgeList)
            >>> net.realizePitch(pitch.Pitch('G3'))
            [G3, A3, B3, C4, D4, E4, F#4, G4]
            ⁠ 
            >>> net.realizePitch(pitch.Pitch('G3'), 5) # G3 is the fifth (scale) degree
            [C3, D3, E3, F3, G3, A3, B3, C4]



            >>> net.realizePitch(pitch.Pitch('G3'), 7) # G3 is the seventh (scale) degree
            [A-2, B-2, C3, D-3, E-3, F3, G3, A-3]
            ⁠ 
            >>> net.realizePitch(pitch.Pitch('f#3'), 1, 'f2', 'f3')
            [E#2, F#2, G#2, A#2, B2, C#3, D#3, E#3]



            >>> net.realizePitch(pitch.Pitch('a#2'), 7, 'c6', 'c7')
            [C#6, D#6, E6, F#6, G#6, A#6, B6]


            Circle of fifths




            >>> edgeList = ['P5', 'P5', 'P5', 'P5', 'P5', 'P5', 'd6', 'P5', 'P5', 'P5', 'P5', 'P5']
            >>> net5ths = intervalNetwork.BoundIntervalNetwork()
            >>> net5ths.fillBiDirectedEdges(edgeList)
            >>> net5ths.realizePitch(pitch.Pitch('C1'))
            [C1, G1, D2, A2, E3, B3, F#4, D-5, A-5, E-6, B-6, F7, C8]
            >>> net5ths.realizePitch(pitch.Pitch('C2'))
            [C2, G2, D3, A3, E4, B4, F#5, D-6, A-6, E-7, B-7, F8, C9]




        .. method:: realizePitchByDegree(pitchReference, nodeId=None, nodeDegreeTargets=[1], minPitch=None, maxPitch=None, direction='ascending', alteredDegrees={})

            Realize the native nodes of this network based on a pitch assigned to a valid `nodeId`, where `nodeId` can be specified by integer (starting from 1) or key (a tuple of origin, destination keys).

            The `nodeDegreeTargets` specifies the the degrees to be included within the specified range.



            >>> from music21 import *
            >>> edgeList = ['M2', 'M2', 'm2', 'M2', 'M2', 'M2', 'm2']
            >>> net = intervalNetwork.BoundIntervalNetwork()
            >>> net.fillBiDirectedEdges(edgeList)
            ⁠ 
            >>> net.realizePitchByDegree('g', 5, [1,5], 'c2', 'c4')
            [C2, G2, C3, G3, C4]



            >>> net.realizePitchByDegree('g', 5, [1,2,3], 'c1', 'c6')
            [C1, D1, E1, C2, D2, E2, C3, D3, E3, C4, D4, E4, C5, D5, E5, C6]
            ⁠ 
            >>> net.realizePitchByDegree('c', 1, [1,5], 'c3', 'c6')
            [C3, G3, C4, G4, C5, G5, C6]




        .. method:: realizeTermini(pitchReference, nodeId=None, alteredDegrees={})

            Realize the pithches of the 'natural' terminus of a network. This (presently) must be done by ascending, and assumes only one valid terminus for both extremes.

            This suggests that in practice termini should not be affected by directionality.



            >>> from music21 import *
            >>> edgeList = ['M2', 'M2', 'm2', 'M2', 'M2', 'M2', 'm2']
            >>> net = intervalNetwork.BoundIntervalNetwork()
            >>> net.fillBiDirectedEdges(edgeList)
            >>> net.realizeTermini(pitch.Pitch('G3'))
            (G3, G4)
            >>> net.realizeTermini(pitch.Pitch('a6'))
            (A6, A7)



        .. method:: transposePitchAndApplySimplification(intervalObj, pitchObj)


            transposes the pitch according to the given interval object and
            uses the simplification of the `pitchSimplification` property
            to simplify it afterwards.





            >>> from music21 import *
            >>> b = intervalNetwork.BoundIntervalNetwork()
            >>> b.pitchSimplification # default
            'maxAccidental'
            >>> i = interval.Interval('m2')
            >>> p = pitch.Pitch("C4")
            >>> allPitches = []
            >>> for j in range(15):
            ...    p = b.transposePitchAndApplySimplification(i, p)
            ...    allPitches.append(p)
            >>> allPitches
            [D-4, D4, E-4, F-4, F4, G-4, G4, A-4, A4, B-4, C-5, C5, D-5, D5, E-5]




            >>> b.pitchSimplification = 'mostCommon'
            >>> p = pitch.Pitch("C4")
            >>> allPitches = []
            >>> for j in range(15):
            ...    p = b.transposePitchAndApplySimplification(i, p)
            ...    allPitches.append(p)
            >>> allPitches
            [C#4, D4, E-4, E4, F4, F#4, G4, A-4, A4, B-4, B4, C5, C#5, D5, E-5]


            PitchSimplifcation can also be specified in the creation of the BoundIntervalNetwork object




            >>> b = intervalNetwork.BoundIntervalNetwork(pitchSimplification = None)
            >>> p = pitch.Pitch("C4")
            >>> allPitches = []
            >>> for j in range(5):
            ...    p = b.transposePitchAndApplySimplification(i, p)
            ...    allPitches.append(p)
            >>> allPitches
            [D-4, E--4, F--4, G---4, A----4]



            Note that beyond quadruple flats or sharps, pitchSimplification is automatic:




            >>> p
            A----4
            >>> b.transposePitchAndApplySimplification(i, p)
            F#4





        .. method:: weightedSelection(edges, nodes)

            Perform weighted random selection on a parallel list of edges and corresponding nodes.



            >>> from music21 import *
            >>> n1 = intervalNetwork.Node(id='a', weight=1000000)
            >>> n2 = intervalNetwork.Node(id='b', weight=1)
            >>> e1 = intervalNetwork.Edge(interval.Interval('m3'), id='a')
            >>> e2 = intervalNetwork.Edge(interval.Interval('m3'), id='b')
            >>> net = intervalNetwork.BoundIntervalNetwork()
            >>> e, n = net.weightedSelection([e1, e2], [n1, n2])
            >>> e.id # note: this may fail as there is a slight chance to get 'b'
            'a'
            >>> n.id
            'a'




Edge
----



.. class:: Edge(intervalData=None, id=None, direction='bi')

    Abstraction of an Interval as an Edge.

    Edges store an Interval object as well as a pathway direction specification. The pathway is the route through the network from terminus to terminus, and can either by ascending or descending.

    For directed Edges, the direction of the Interval may be used to
    suggest non-pitch ascending movements (even if the pathway direction is ascending).

    Weight values, as well as other attributes, can be stored.



    >>> from music21 import *
    >>> i = interval.Interval('M3')
    >>> e = intervalNetwork.Edge(i)
    >>> i is e.interval
    True



    **Edge** **attributes**

        Attributes without Documentation: `id`, `weight`

    **Edge** **properties**

        .. attribute:: connections


            Callable as a property (.connections) or as a method
            (.getConnections(direction)):

            Return a list of connections between Nodes, represented as pairs
            of Node ids. If a direction is specified, and if the Edge is
            directional, only the desired directed values will be returned.



            >>> from music21 import *
            >>> i = interval.Interval('M3')
            >>> e1 = intervalNetwork.Edge(i, id=0)
            >>> n1 = intervalNetwork.Node(id='terminusLow')
            >>> n2 = intervalNetwork.Node(id=1)
            ⁠ 
            >>> e1.addBiDirectedConnections(n1, n2)
            >>> e1.connections
            [('terminusLow', 1), (1, 'terminusLow')]
            >>> e1.getConnections('ascending')
            [('terminusLow', 1)]
            >>> e1.getConnections('descending')
            [(1, 'terminusLow')]




        .. attribute:: direction

            Return the direction of the Edge.



            >>> from music21 import *
            >>> i = interval.Interval('M3')
            >>> e1 = intervalNetwork.Edge(i, id=0)
            >>> n1 = intervalNetwork.Node(id=0)
            >>> n2 = intervalNetwork.Node(id=1)
            >>> e1.addDirectedConnection(n1, n2, 'ascending')
            >>> e1.direction
            'ascending'



        .. attribute:: interval

            Return the stored Interval object



            >>> from music21 import *
            >>> i = interval.Interval('M3')
            >>> e1 = intervalNetwork.Edge(i, id=0)
            >>> n1 = intervalNetwork.Node(id=0)
            >>> n2 = intervalNetwork.Node(id=1)
            >>> e1.addDirectedConnection(n1, n2, 'ascending')
            >>> e1.interval
            <music21.interval.Interval M3>



    **Edge** **methods**

        .. method:: addBiDirectedConnections(n1, n2)

            Provide two Edge objects that pass through
            this Node, in the direction from the first to the second.



            >>> from music21 import *
            >>> i = interval.Interval('M3')
            >>> e1 = intervalNetwork.Edge(i, id=0)
            >>> n1 = intervalNetwork.Node(id='terminusLow')
            >>> n2 = intervalNetwork.Node(id=1)
            ⁠ 
            >>> e1.addBiDirectedConnections(n1, n2)
            >>> e1.connections
            [('terminusLow', 1), (1, 'terminusLow')]
            >>> e1
            <music21.intervalNetwork.Edge bi M3 [('terminusLow',1),(1,'terminusLow')]>



        .. method:: addDirectedConnection(n1, n2, direction=None)

            Provide two Node objects that connect this Edge, in the direction from the first to the second.

            When calling directly, a direction, either
            ascending or descending, should be set here;
            this will override whatever the interval is.
            If None, this will not be set.



            >>> from music21 import *
            >>> i = interval.Interval('M3')
            >>> e1 = intervalNetwork.Edge(i, id=0)
            >>> n1 = intervalNetwork.Node(id=0)
            >>> n2 = intervalNetwork.Node(id=1)
            ⁠ 
            >>> e1.addDirectedConnection(n1, n2, 'ascending')
            >>> e1.connections
            [(0, 1)]
            >>> e1
            <music21.intervalNetwork.Edge ascending M3 [(0,1)]>



        .. method:: getConnections(direction=None)


            Callable as a property (.connections) or as a method
            (.getConnections(direction)):

            Return a list of connections between Nodes, represented as pairs
            of Node ids. If a direction is specified, and if the Edge is
            directional, only the desired directed values will be returned.



            >>> from music21 import *
            >>> i = interval.Interval('M3')
            >>> e1 = intervalNetwork.Edge(i, id=0)
            >>> n1 = intervalNetwork.Node(id='terminusLow')
            >>> n2 = intervalNetwork.Node(id=1)
            ⁠ 
            >>> e1.addBiDirectedConnections(n1, n2)
            >>> e1.connections
            [('terminusLow', 1), (1, 'terminusLow')]
            >>> e1.getConnections('ascending')
            [('terminusLow', 1)]
            >>> e1.getConnections('descending')
            [(1, 'terminusLow')]





IntervalNetwork
---------------



.. class:: IntervalNetwork()



Node
----



.. class:: Node(id=None, degree=None, weight=1.0)

    Abstraction of an unrealized Pitch Node.

    The Node `id` is used to storing connections in Edges and has no real meaning.

    Terminal Nodes have special ids: 'terminusLow', 'terminusHigh'

    The Node `degree` is translated to scale degrees in various applications, and is used to request a pitch from the network.

    The `weight` attribute is used to probabilistically select between multiple nodes when multiple nodes satisfy either a branching option in a pathway or a request for a degree.




    **Node** **attributes**

        Attributes without Documentation: `weight`, `id`, `degree`


