Quiver - Combinatorics

Skip to content
Back to top
View this page
Edit this page

# Quiver

A quiver is an oriented graph without loops, two-cycles, or multiple edges. The edges are labelled by pairs \((i,-j)\) (with \(i\) and \(j\) being positive integers) such that the matrix \(M = (m_{ab})\) with \(m_{ab} = i, m_{ba} = -j\) for an edge \((i,-j)\) between vertices \(a\) and \(b\) is skew-symmetrizable.

Warning

This is not the standard definition of a quiver. Normally, in cluster algebra theory, a quiver is defined as an oriented graph without loops and two-cycles but with multiple edges allowed; the edges are unlabelled. This notion of quivers, however, can be seen as a particular case of our notion of quivers. Namely, if we have a quiver (in the regular sense of this word) with (precisely) \(i\) edges from \(a\) to \(b\), then we represent it by a quiver (in our sense of this word) with an edge from \(a\) to \(b\) labelled by the pair \((i,-i)\).

For the compendium on the cluster algebra and quiver package see [MS2011]

AUTHORS:

- Gregg Musiker

- Christian Stump

See also

For mutation types of combinatorial quivers, see `QuiverMutationType()`. Cluster seeds are closely related to `ClusterSeed()`.

class sage.combinat.cluster_algebra_quiver.quiver.ClusterQuiver(data, frozen=None, user_labels=None)

  Bases: `SageObject`

  The quiver associated to an exchange matrix.

  INPUT:

  - `data` – can be any of the following:

        - :class:`QuiverMutationType`

    - `str` – string representing a `QuiverMutationType` or a common quiver type (see Examples)

    - `ClusterQuiver`

    - `Matrix` – a skew-symmetrizable matrix

    - `DiGraph` – must be the input data for a quiver

    - List of edges – must be the edge list of a digraph for a quiver

  - `frozen` – (default: `None`) sets the list of frozen variables if the input type is a `DiGraph`, it is ignored otherwise

  - `user_labels` – (default: `None`) sets the names of the labels for the vertices of the quiver if the input type is not a `DiGraph`; otherwise it is ignored

  EXAMPLES:

  From a `QuiverMutationType`:

  Sage

      sage: Q = ClusterQuiver(['A',5]); Q
      Quiver on 5 vertices of type ['A', 5]

      sage: Q = ClusterQuiver(['B',2]); Q
      Quiver on 2 vertices of type ['B', 2]
      sage: Q2 = ClusterQuiver(['C',2]); Q2
      Quiver on 2 vertices of type ['B', 2]
      sage: MT = Q.mutation_type(); MT.standard_quiver() == Q
      True
      sage: MT = Q2.mutation_type(); MT.standard_quiver() == Q2
      False

      sage: Q = ClusterQuiver(['A',[2,5],1]); Q
      Quiver on 7 vertices of type ['A', [2, 5], 1]

      sage: Q = ClusterQuiver(['A', [5,0],1]); Q
      Quiver on 5 vertices of type ['D', 5]
      sage: Q.is_finite()
      True
      sage: Q.is_acyclic()
      False

      sage: Q = ClusterQuiver(['F', 4, [2,1]]); Q
      Quiver on 6 vertices of type ['F', 4, [1, 2]]
      sage: MT = Q.mutation_type(); MT.standard_quiver() == Q
      False
      sage: dg = Q.digraph(); Q.mutate([2,1,4,0,5,3])
      sage: dg2 = Q.digraph(); dg2.is_isomorphic(dg,edge_labels=True)
      False
      sage: dg2.is_isomorphic(MT.standard_quiver().digraph(),edge_labels=True)
      True

      sage: Q = ClusterQuiver(['G',2, (3,1)]); Q
      Quiver on 4 vertices of type ['G', 2, [1, 3]]
      sage: MT = Q.mutation_type(); MT.standard_quiver() == Q
      False

      sage: Q = ClusterQuiver(['GR',[3,6]]); Q
      Quiver on 4 vertices of type ['D', 4]
      sage: MT = Q.mutation_type(); MT.standard_quiver() == Q
      False

      sage: Q = ClusterQuiver(['GR',[3,7]]); Q
      Quiver on 6 vertices of type ['E', 6]

      sage: Q = ClusterQuiver(['TR',2]); Q
      Quiver on 3 vertices of type ['A', 3]
      sage: MT = Q.mutation_type(); MT.standard_quiver() == Q
      False
      sage: Q.mutate([1,0]); MT.standard_quiver() == Q
      True

      sage: Q = ClusterQuiver(['TR',3]); Q
      Quiver on 6 vertices of type ['D', 6]
      sage: MT = Q.mutation_type(); MT.standard_quiver() == Q
      False

  Python

      >>> from sage.all import *
      >>> Q = ClusterQuiver(['A',Integer(5)]); Q
      Quiver on 5 vertices of type ['A', 5]

      >>> Q = ClusterQuiver(['B',Integer(2)]); Q
      Quiver on 2 vertices of type ['B', 2]
      >>> Q2 = ClusterQuiver(['C',Integer(2)]); Q2
      Quiver on 2 vertices of type ['B', 2]
      >>> MT = Q.mutation_type(); MT.standard_quiver() == Q
      True
      >>> MT = Q2.mutation_type(); MT.standard_quiver() == Q2
      False

      >>> Q = ClusterQuiver(['A',[Integer(2),Integer(5)],Integer(1)]); Q
      Quiver on 7 vertices of type ['A', [2, 5], 1]

      >>> Q = ClusterQuiver(['A', [Integer(5),Integer(0)],Integer(1)]); Q
      Quiver on 5 vertices of type ['D', 5]
      >>> Q.is_finite()
      True
      >>> Q.is_acyclic()
      False

      >>> Q = ClusterQuiver(['F', Integer(4), [Integer(2),Integer(1)]]); Q
      Quiver on 6 vertices of type ['F', 4, [1, 2]]
      >>> MT = Q.mutation_type(); MT.standard_quiver() == Q
      False
      >>> dg = Q.digraph(); Q.mutate([Integer(2),Integer(1),Integer(4),Integer(0),Integer(5),Integer(3)])
      >>> dg2 = Q.digraph(); dg2.is_isomorphic(dg,edge_labels=True)
      False
      >>> dg2.is_isomorphic(MT.standard_quiver().digraph(),edge_labels=True)
      True

      >>> Q = ClusterQuiver(['G',Integer(2), (Integer(3),Integer(1))]); Q
      Quiver on 4 vertices of type ['G', 2, [1, 3]]
      >>> MT = Q.mutation_type(); MT.standard_quiver() == Q
      False

      >>> Q = ClusterQuiver(['GR',[Integer(3),Integer(6)]]); Q
      Quiver on 4 vertices of type ['D', 4]
      >>> MT = Q.mutation_type(); MT.standard_quiver() == Q
      False

      >>> Q = ClusterQuiver(['GR',[Integer(3),Integer(7)]]); Q
      Quiver on 6 vertices of type ['E', 6]

      >>> Q = ClusterQuiver(['TR',Integer(2)]); Q
      Quiver on 3 vertices of type ['A', 3]
      >>> MT = Q.mutation_type(); MT.standard_quiver() == Q
      False
      >>> Q.mutate([Integer(1),Integer(0)]); MT.standard_quiver() == Q
      True

      >>> Q = ClusterQuiver(['TR',Integer(3)]); Q
      Quiver on 6 vertices of type ['D', 6]
      >>> MT = Q.mutation_type(); MT.standard_quiver() == Q
      False

  From a `ClusterQuiver`:

  Sage

      sage: Q = ClusterQuiver(['A',[2,5],1]); Q
      Quiver on 7 vertices of type ['A', [2, 5], 1]
      sage: T = ClusterQuiver(Q); T
      Quiver on 7 vertices of type ['A', [2, 5], 1]

  [Python]

      >>> from sage.all import *
      >>> Q = ClusterQuiver(['A',[Integer(2),Integer(5)],Integer(1)]); Q
      Quiver on 7 vertices of type ['A', [2, 5], 1]
      >>> T = ClusterQuiver(Q); T
      Quiver on 7 vertices of type ['A', [2, 5], 1]

  From a Matrix:

  Sage

      sage: Q = ClusterQuiver(['A',[2,5],1]); Q
      Quiver on 7 vertices of type ['A', [2, 5], 1]
      sage: T = ClusterQuiver(Q._M); T
      Quiver on 7 vertices

      sage: Q = ClusterQuiver(matrix([[0,1,-1],[-1,0,1],[1,-1,0],[1,2,3]])); Q
      Quiver on 4 vertices with 1 frozen vertex

      sage: Q = ClusterQuiver(matrix([])); Q
      Quiver without vertices

  Python

      >>> from sage.all import *
      >>> Q = ClusterQuiver(['A',[Integer(2),Integer(5)],Integer(1)]); Q
      Quiver on 7 vertices of type ['A', [2, 5], 1]
      >>> T = ClusterQuiver(Q._M); T
      Quiver on 7 vertices

      >>> Q = ClusterQuiver(matrix([[Integer(0),Integer(1),-Integer(1)],[-Integer(1),Integer(0),Integer(1)],[Integer(1),-Integer(1),Integer(0)],[Integer(1),Integer(2),Integer(3)]])); Q
      Quiver on 4 vertices with 1 frozen vertex

      >>> Q = ClusterQuiver(matrix([])); Q
      Quiver without vertices

  From a DiGraph:

  Sage

      sage: Q = ClusterQuiver(['A',[2,5],1]); Q
      Quiver on 7 vertices of type ['A', [2, 5], 1]
      sage: T = ClusterQuiver(Q._digraph); T
      Quiver on 7 vertices

      sage: Q = ClusterQuiver(DiGraph([[1,2],[2,3],[3,4],[4,1]])); Q
      Quiver on 4 vertices

      sage: Q = ClusterQuiver(DiGraph([['a', 'b'], ['b', 'c'], ['c', 'd'], ['d', 'e']]),
      ....:          frozen=['c']); Q
      Quiver on 5 vertices with 1 frozen vertex
      sage: Q.mutation_type()
      [ ['A', 2], ['A', 2] ]
      sage: Q
      Quiver on 5 vertices of type [ ['A', 2], ['A', 2] ]
      with 1 frozen vertex

  [Python]

      >>> from sage.all import *
      >>> Q = ClusterQuiver(['A',[Integer(2),Integer(5)],Integer(1)]); Q
      Quiver on 7 vertices of type ['A', [2, 5], 1]
      >>> T = ClusterQuiver(Q._digraph); T
      Quiver on 7 vertices

      >>> Q = ClusterQuiver(DiGraph([[Integer(1),Integer(2)],[Integer(2),Integer(3)],[Integer(3),Integer(4)],[Integer(4),Integer(1)]])); Q
      Quiver on 4 vertices

      >>> Q = ClusterQuiver(DiGraph([['a', 'b'], ['b', 'c'], ['c', 'd'], ['d', 'e']]),
      ...          frozen=['c']); Q
      Quiver on 5 vertices with 1 frozen vertex
      >>> Q.mutation_type()
      [ ['A', 2], ['A', 2] ]
      >>> Q
      Quiver on 5 vertices of type [ ['A', 2], ['A', 2] ]
      with 1 frozen vertex

  From a List of edges:

  Sage

      sage: Q = ClusterQuiver(['A',[2,5],1]); Q
      Quiver on 7 vertices of type ['A', [2, 5], 1]
      sage: T = ClusterQuiver(Q._digraph.edges(sort=True)); T
      Quiver on 7 vertices

      sage: Q = ClusterQuiver([[1, 2], [2, 3], [3, 4], [4, 1]]); Q
      Quiver on 4 vertices

  Python

      >>> from sage.all import *
      >>> Q = ClusterQuiver(['A',[Integer(2),Integer(5)],Integer(1)]); Q
      Quiver on 7 vertices of type ['A', [2, 5], 1]
      >>> T = ClusterQuiver(Q._digraph.edges(sort=True)); T
      Quiver on 7 vertices

      >>> Q = ClusterQuiver([[Integer(1), Integer(2)], [Integer(2), Integer(3)], [Integer(3), Integer(4)], [Integer(4), Integer(1)]]); Q
      Quiver on 4 vertices

  b_matrix()

    Return the b-matrix of `self`.

    EXAMPLES:

    Sage

        sage: ClusterQuiver(['A',4]).b_matrix()
        [ 0  1  0  0]
        [-1  0 -1  0]
        [ 0  1  0  1]
        [ 0  0 -1  0]

        sage: ClusterQuiver(['B',4]).b_matrix()
        [ 0  1  0  0]
        [-1  0 -1  0]
        [ 0  1  0  1]
        [ 0  0 -2  0]

        sage: ClusterQuiver(['D',4]).b_matrix()
        [ 0  1  0  0]
        [-1  0 -1 -1]
        [ 0  1  0  0]
        [ 0  1  0  0]

        sage: ClusterQuiver(QuiverMutationType([['A',2],['B',2]])).b_matrix()
        [ 0  1  0  0]
        [-1  0  0  0]
        [ 0  0  0  1]
        [ 0  0 -2  0]

    Python

        >>> from sage.all import *
        >>> ClusterQuiver(['A',Integer(4)]).b_matrix()
        [ 0  1  0  0]
        [-1  0 -1  0]
        [ 0  1  0  1]
        [ 0  0 -1  0]

        >>> ClusterQuiver(['B',Integer(4)]).b_matrix()
        [ 0  1  0  0]
        [-1  0 -1  0]
        [ 0  1  0  1]
        [ 0  0 -2  0]

        >>> ClusterQuiver(['D',Integer(4)]).b_matrix()
        [ 0  1  0  0]
        [-1  0 -1 -1]
        [ 0  1  0  0]
        [ 0  1  0  0]

        >>> ClusterQuiver(QuiverMutationType([['A',Integer(2)],['B',Integer(2)]])).b_matrix()
        [ 0  1  0  0]
        [-1  0  0  0]
        [ 0  0  0  1]
        [ 0  0 -2  0]

  canonical_label(certificate=False)

    Return the canonical labelling of `self`.

    See `sage.graphs.generic_graph.GenericGraph.canonical_label()`.

    INPUT:

    - `certificate` – boolean (default: `False`); if `True`, the dictionary from `self.vertices()` to the vertices of the returned quiver is returned as well

    EXAMPLES:

    Sage

        sage: Q = ClusterQuiver(['A',4]); Q.digraph().edges(sort=True)
        [(0, 1, (1, -1)), (2, 1, (1, -1)), (2, 3, (1, -1))]

        sage: T = Q.canonical_label(); T.digraph().edges(sort=True)
        [(0, 3, (1, -1)), (1, 2, (1, -1)), (1, 3, (1, -1))]

        sage: T, iso = Q.canonical_label(certificate=True)
        sage: T.digraph().edges(sort=True); iso
        [(0, 3, (1, -1)), (1, 2, (1, -1)), (1, 3, (1, -1))]
        {0: 0, 1: 3, 2: 1, 3: 2}

        sage: Q = ClusterQuiver(QuiverMutationType([['B',2],['A',1]])); Q
        Quiver on 3 vertices of type [ ['B', 2], ['A', 1] ]

        sage: Q.canonical_label()
        Quiver on 3 vertices of type [ ['A', 1], ['B', 2] ]

        sage: Q.canonical_label(certificate=True)
        (Quiver on 3 vertices of type [ ['A', 1], ['B', 2] ], {0: 1, 1: 2, 2: 0})

    Python

        >>> from sage.all import *
        >>> Q = ClusterQuiver(['A',Integer(4)]); Q.digraph().edges(sort=True)
        [(0, 1, (1, -1)), (2, 1, (1, -1)), (2, 3, (1, -1))]

        >>> T = Q.canonical_label(); T.digraph().edges(sort=True)
        [(0, 3, (1, -1)), (1, 2, (1, -1)), (1, 3, (1, -1))]

        >>> T, iso = Q.canonical_label(certificate=True)
        >>> T.digraph().edges(sort=True); iso
        [(0, 3, (1, -1)), (1, 2, (1, -1)), (1, 3, (1, -1))]
        {0: 0, 1: 3, 2: 1, 3: 2}

        >>> Q = ClusterQuiver(QuiverMutationType([['B',Integer(2)],['A',Integer(1)]])); Q
        Quiver on 3 vertices of type [ ['B', 2], ['A', 1] ]

        >>> Q.canonical_label()
        Quiver on 3 vertices of type [ ['A', 1], ['B', 2] ]

        >>> Q.canonical_label(certificate=True)
        (Quiver on 3 vertices of type [ ['A', 1], ['B', 2] ], {0: 1, 1: 2, 2: 0})

  d_vector_fan()

    Return the d-vector fan associated with the quiver.

    It is the fan whose maximal cones are generated by the d-matrices of the clusters.

    This is a complete simplicial fan (and even smooth when the initial quiver is acyclic). It only makes sense for quivers of finite type.

    EXAMPLES:

    Sage

        sage: # needs sage.geometry.polyhedron sage.libs.singular
        sage: Fd = ClusterQuiver([[1,2]]).d_vector_fan(); Fd
        Rational polyhedral fan in 2-d lattice N
        sage: Fd.ngenerating_cones()
        5
        sage: Fd = ClusterQuiver([[1,2],[2,3]]).d_vector_fan(); Fd
        Rational polyhedral fan in 3-d lattice N
        sage: Fd.ngenerating_cones()
        14
        sage: Fd.is_smooth()
        True
        sage: Fd = ClusterQuiver([[1,2],[2,3],[3,1]]).d_vector_fan(); Fd
        Rational polyhedral fan in 3-d lattice N
        sage: Fd.ngenerating_cones()
        14
        sage: Fd.is_smooth()
        False

    Python

        >>> from sage.all import *
        >>> # needs sage.geometry.polyhedron sage.libs.singular
        >>> Fd = ClusterQuiver([[Integer(1),Integer(2)]]).d_vector_fan(); Fd
        Rational polyhedral fan in 2-d lattice N
        >>> Fd.ngenerating_cones()
        5
        >>> Fd = ClusterQuiver([[Integer(1),Integer(2)],[Integer(2),Integer(3)]]).d_vector_fan(); Fd
        Rational polyhedral fan in 3-d lattice N
        >>> Fd.ngenerating_cones()
        14
        >>> Fd.is_smooth()
        True
        >>> Fd = ClusterQuiver([[Integer(1),Integer(2)],[Integer(2),Integer(3)],[Integer(3),Integer(1)]]).d_vector_fan(); Fd
        Rational polyhedral fan in 3-d lattice N
        >>> Fd.ngenerating_cones()
        14
        >>> Fd.is_smooth()
        False

  digraph()

    Return the underlying digraph of `self`.

    EXAMPLES:

    Sage

        sage: ClusterQuiver(['A',1]).digraph()
        Digraph on 1 vertex
        sage: list(ClusterQuiver(['A',1]).digraph())
        [0]
        sage: ClusterQuiver(['A',1]).digraph().edges(sort=True)
        []

        sage: ClusterQuiver(['A',4]).digraph()
        Digraph on 4 vertices
        sage: ClusterQuiver(['A',4]).digraph().edges(sort=True)
        [(0, 1, (1, -1)), (2, 1, (1, -1)), (2, 3, (1, -1))]

        sage: ClusterQuiver(['B',4]).digraph()
        Digraph on 4 vertices
        sage: ClusterQuiver(['A',4]).digraph().edges(sort=True)
        [(0, 1, (1, -1)), (2, 1, (1, -1)), (2, 3, (1, -1))]

        sage: ClusterQuiver(QuiverMutationType([['A',2],['B',2]])).digraph()
        Digraph on 4 vertices

        sage: ClusterQuiver(QuiverMutationType([['A',2],['B',2]])).digraph().edges(sort=True)
        [(0, 1, (1, -1)), (2, 3, (1, -2))]

        sage: ClusterQuiver(['C', 4], user_labels = ['x', 'y', 'z', 'w']).digraph().edges(sort=True)
        [('x', 'y', (1, -1)), ('z', 'w', (2, -1)), ('z', 'y', (1, -1))]

    Python

        >>> from sage.all import *
        >>> ClusterQuiver(['A',Integer(1)]).digraph()
        Digraph on 1 vertex
        >>> list(ClusterQuiver(['A',Integer(1)]).digraph())
        [0]
        >>> ClusterQuiver(['A',Integer(1)]).digraph().edges(sort=True)
        []

        >>> ClusterQuiver(['A',Integer(4)]).digraph()
        Digraph on 4 vertices
        >>> ClusterQuiver(['A',Integer(4)]).digraph().edges(sort=True)
        [(0, 1, (1, -1)), (2, 1, (1, -1)), (2, 3, (1, -1))]

        >>> ClusterQuiver(['B',Integer(4)]).digraph()
        Digraph on 4 vertices
        >>> ClusterQuiver(['A',Integer(4)]).digraph().edges(sort=True)
        [(0, 1, (1, -1)), (2, 1, (1, -1)), (2, 3, (1, -1))]

        >>> ClusterQuiver(QuiverMutationType([['A',Integer(2)],['B',Integer(2)]])).digraph()
        Digraph on 4 vertices

        >>> ClusterQuiver(QuiverMutationType([['A',Integer(2)],['B',Integer(2)]])).digraph().edges(sort=True)
        [(0, 1, (1, -1)), (2, 3, (1, -2))]

        >>> ClusterQuiver(['C', Integer(4)], user_labels = ['x', 'y', 'z', 'w']).digraph().edges(sort=True)
        [('x', 'y', (1, -1)), ('z', 'w', (2, -1)), ('z', 'y', (1, -1))]

  exchangeable_part()

    Return the restriction to the principal part (i.e. exchangeable part) of `self`, the subquiver obtained by deleting the frozen vertices of `self`.

    EXAMPLES:

    Sage

        sage: Q = ClusterQuiver(['A',4])
        sage: T = ClusterQuiver(Q.digraph().edges(sort=True), frozen=[3])
        sage: T.digraph().edges(sort=True)
        [(0, 1, (1, -1)), (2, 1, (1, -1)), (2, 3, (1, -1))]

        sage: T.exchangeable_part().digraph().edges(sort=True)
        [(0, 1, (1, -1)), (2, 1, (1, -1))]

        sage: Q2 = Q.principal_extension()
        sage: Q3 = Q2.principal_extension()
        sage: Q2.exchangeable_part() == Q3.exchangeable_part()
        True

    Python

        >>> from sage.all import *
        >>> Q = ClusterQuiver(['A',Integer(4)])
        >>> T = ClusterQuiver(Q.digraph().edges(sort=True), frozen=[Integer(3)])
        >>> T.digraph().edges(sort=True)
        [(0, 1, (1, -1)), (2, 1, (1, -1)), (2, 3, (1, -1))]

        >>> T.exchangeable_part().digraph().edges(sort=True)
        [(0, 1, (1, -1)), (2, 1, (1, -1))]

        >>> Q2 = Q.principal_extension()
        >>> Q3 = Q2.principal_extension()
        >>> Q2.exchangeable_part() == Q3.exchangeable_part()
        True

  first_sink()

    Return the first vertex of `self` that is a sink.

    EXAMPLES:

    Sage

        sage: Q = ClusterQuiver(['A',5])
        sage: Q.mutate([1,2,4,3,2])
        sage: Q.first_sink()
        0

    Python

        >>> from sage.all import *
        >>> Q = ClusterQuiver(['A',Integer(5)])
        >>> Q.mutate([Integer(1),Integer(2),Integer(4),Integer(3),Integer(2)])
        >>> Q.first_sink()
        0

  first_source()

    Return the first vertex of `self` that is a source.

    EXAMPLES:

    Sage

        sage: Q = ClusterQuiver(['A',5])
        sage: Q.mutate([2,1,3,4,2])
        sage: Q.first_source()
        1

    Python

        >>> from sage.all import *
        >>> Q = ClusterQuiver(['A',Integer(5)])
        >>> Q.mutate([Integer(2),Integer(1),Integer(3),Integer(4),Integer(2)])
        >>> Q.first_source()
        1

  free_vertices()

    Return the list of free vertices of `self`.

    EXAMPLES:

    Sage

        sage: Q = ClusterQuiver(DiGraph([['a', 'b'], ['c', 'b'], ['c', 'd'], ['e', 'd']]),
        ....:                   frozen=['b', 'd'])
        sage: Q.free_vertices()
        ['a', 'c', 'e']

    Python

        >>> from sage.all import *
        >>> Q = ClusterQuiver(DiGraph([['a', 'b'], ['c', 'b'], ['c', 'd'], ['e', 'd']]),
        ...                   frozen=['b', 'd'])
        >>> Q.free_vertices()
        ['a', 'c', 'e']

  frozen_vertices()

    Return the list of frozen vertices of `self`.

    EXAMPLES:

    Sage

        sage: Q = ClusterQuiver(DiGraph([['a', 'b'], ['c', 'b'], ['c', 'd'], ['e', 'd']]),
        ....:                   frozen=['b', 'd'])
        sage: sorted(Q.frozen_vertices())
        ['b', 'd']

    Python

        >>> from sage.all import *
        >>> Q = ClusterQuiver(DiGraph([['a', 'b'], ['c', 'b'], ['c', 'd'], ['e', 'd']]),
        ...                   frozen=['b', 'd'])
        >>> sorted(Q.frozen_vertices())
        ['b', 'd']

  g_vector_fan()

    Return the g-vector fan associated with the quiver.

    It is the fan whose maximal cones are generated by the g-matrices of the clusters.

    This is a complete simplicial fan. It is only supported for quivers of finite type.

    EXAMPLES:

    Sage

        sage: Fg = ClusterQuiver([[1,2]]).g_vector_fan(); Fg
        Rational polyhedral fan in 2-d lattice N
        sage: Fg.ngenerating_cones()
        5

        sage: Fg = ClusterQuiver([[1,2],[2,3]]).g_vector_fan(); Fg
        Rational polyhedral fan in 3-d lattice N
        sage: Fg.ngenerating_cones()
        14
        sage: Fg.is_smooth()
        True

        sage: Fg = ClusterQuiver([[1,2],[2,3],[3,1]]).g_vector_fan(); Fg
        Rational polyhedral fan in 3-d lattice N
        sage: Fg.ngenerating_cones()
        14
        sage: Fg.is_smooth()
        True

    Python

        >>> from sage.all import *
        >>> Fg = ClusterQuiver([[Integer(1),Integer(2)]]).g_vector_fan(); Fg
        Rational polyhedral fan in 2-d lattice N
        >>> Fg.ngenerating_cones()
        5

        >>> Fg = ClusterQuiver([[Integer(1),Integer(2)],[Integer(2),Integer(3)]]).g_vector_fan(); Fg
        Rational polyhedral fan in 3-d lattice N
        >>> Fg.ngenerating_cones()
        14
        >>> Fg.is_smooth()
        True

        >>> Fg = ClusterQuiver([[Integer(1),Integer(2)],[Integer(2),Integer(3)],[Integer(3),Integer(1)]]).g_vector_fan(); Fg
        Rational polyhedral fan in 3-d lattice N
        >>> Fg.ngenerating_cones()
        14
        >>> Fg.is_smooth()
        True

  interact(fig_size=1, circular=True)

    Start an interactive window for cluster quiver mutations.

    Only in Jupyter notebook mode.

    INPUT:

    - `fig_size` – (default: 1) factor by which the size of the plot is multiplied

    - `circular` – boolean (default: `True`); if `True`, the circular plot is chosen, otherwise >>spring<< is used

  is_acyclic()

    Return true if `self` is acyclic.

    EXAMPLES:

    Sage

        sage: ClusterQuiver(['A',4]).is_acyclic()
        True

        sage: ClusterQuiver(['A',[2,1],1]).is_acyclic()
        True

        sage: ClusterQuiver([[0,1],[1,2],[2,0]]).is_acyclic()
        False

    Python

        >>> from sage.all import *
        >>> ClusterQuiver(['A',Integer(4)]).is_acyclic()
        True

        >>> ClusterQuiver(['A',[Integer(2),Integer(1)],Integer(1)]).is_acyclic()
        True

        >>> ClusterQuiver([[Integer(0),Integer(1)],[Integer(1),Integer(2)],[Integer(2),Integer(0)]]).is_acyclic()
        False

  is_bipartite(return_bipartition=False)

    Return `True` if `self` is bipartite.

    EXAMPLES:

    Sage

        sage: ClusterQuiver(['A',[3,3],1]).is_bipartite()
        True

        sage: ClusterQuiver(['A',[4,3],1]).is_bipartite()
        False

    Python

        >>> from sage.all import *
        >>> ClusterQuiver(['A',[Integer(3),Integer(3)],Integer(1)]).is_bipartite()
        True

        >>> ClusterQuiver(['A',[Integer(4),Integer(3)],Integer(1)]).is_bipartite()
        False

  is_finite()

    Return `True` if `self` is of finite type.

    EXAMPLES:

    Sage

        sage: Q = ClusterQuiver(['A',3])
        sage: Q.is_finite()
        True
        sage: Q = ClusterQuiver(['A',[2,2],1])
        sage: Q.is_finite()
        False
        sage: Q = ClusterQuiver([['A',3],['B',3]])
        sage: Q.is_finite()
        True
        sage: Q = ClusterQuiver(['T',[4,4,4]])
        sage: Q.is_finite()
        False
        sage: Q = ClusterQuiver([['A',3],['T',[4,4,4]]])
        sage: Q.is_finite()
        False
        sage: Q = ClusterQuiver([['A',3],['T',[2,2,3]]])
        sage: Q.is_finite()
        True
        sage: Q = ClusterQuiver([['A',3],['D',5]])
        sage: Q.is_finite()
        True
        sage: Q = ClusterQuiver([['A',3],['D',5,1]])
        sage: Q.is_finite()
        False

        sage: Q = ClusterQuiver([[0,1,2],[1,2,2],[2,0,2]])
        sage: Q.is_finite()
        False

        sage: Q = ClusterQuiver([[0,1,2],[1,2,2],[2,0,2],[3,4,1],[4,5,1]])
        sage: Q.is_finite()
        False

    Python

        >>> from sage.all import *
        >>> Q = ClusterQuiver(['A',Integer(3)])
        >>> Q.is_finite()
        True
        >>> Q = ClusterQuiver(['A',[Integer(2),Integer(2)],Integer(1)])
        >>> Q.is_finite()
        False
        >>> Q = ClusterQuiver([['A',Integer(3)],['B',Integer(3)]])
        >>> Q.is_finite()
        True
        >>> Q = ClusterQuiver(['T',[Integer(4),Integer(4),Integer(4)]])
        >>> Q.is_finite()
        False
        >>> Q = ClusterQuiver([['A',Integer(3)],['T',[Integer(4),Integer(4),Integer(4)]]])
        >>> Q.is_finite()
        False
        >>> Q = ClusterQuiver([['A',Integer(3)],['T',[Integer(2),Integer(2),Integer(3)]]])
        >>> Q.is_finite()
        True
        >>> Q = ClusterQuiver([['A',Integer(3)],['D',Integer(5)]])
        >>> Q.is_finite()
        True
        >>> Q = ClusterQuiver([['A',Integer(3)],['D',Integer(5),Integer(1)]])
        >>> Q.is_finite()
        False

        >>> Q = ClusterQuiver([[Integer(0),Integer(1),Integer(2)],[Integer(1),Integer(2),Integer(2)],[Integer(2),Integer(0),Integer(2)]])
        >>> Q.is_finite()
        False

        >>> Q = ClusterQuiver([[Integer(0),Integer(1),Integer(2)],[Integer(1),Integer(2),Integer(2)],[Integer(2),Integer(0),Integer(2)],[Integer(3),Integer(4),Integer(1)],[Integer(4),Integer(5),Integer(1)]])
        >>> Q.is_finite()
        False

  is_mutation_finite(nr_of_checks=None, return_path=False)

    Return whether `self` is mutation-finite.

    This uses a non-deterministic method by random mutations in various directions. This can result in a wrong answer.

    INPUT:

    - `nr_of_checks` – (default: `None`) number of mutations applied; Standard is 500*(number of vertices of `self`)

    - `return_path` – (default: `False`) if `True`, in case of `self` not being mutation finite, a path from `self` to a quiver with an edge label \((a,-b)\) and \(a*b > 4\) is returned

    ALGORITHM:

    A quiver is mutation infinite if and only if every edge label (a,-b) satisfy a*b > 4. Thus, we apply random mutations in random directions

    EXAMPLES:

    Sage

        sage: Q = ClusterQuiver(['A',10])
        sage: Q._mutation_type = None
        sage: Q.is_mutation_finite()
        True

        sage: Q = ClusterQuiver([(0,1),(1,2),(2,3),(3,4),
        ....:                    (4,5),(5,6),(6,7),(7,8),(2,9)])
        sage: Q.is_mutation_finite()
        False

    Python

        >>> from sage.all import *
        >>> Q = ClusterQuiver(['A',Integer(10)])
        >>> Q._mutation_type = None
        >>> Q.is_mutation_finite()
        True

        >>> Q = ClusterQuiver([(Integer(0),Integer(1)),(Integer(1),Integer(2)),(Integer(2),Integer(3)),(Integer(3),Integer(4)),
        ...                    (Integer(4),Integer(5)),(Integer(5),Integer(6)),(Integer(6),Integer(7)),(Integer(7),Integer(8)),(Integer(2),Integer(9))])
        >>> Q.is_mutation_finite()
        False

  m()

    Return the number of frozen vertices of `self`.

    EXAMPLES:

    Sage

        sage: Q = ClusterQuiver(['A',4])
        sage: Q.m()
        0

        sage: T = ClusterQuiver(Q.digraph().edges(sort=True), frozen=[3])
        sage: T.n()
        3
        sage: T.m()
        1

    Python

        >>> from sage.all import *
        >>> Q = ClusterQuiver(['A',Integer(4)])
        >>> Q.m()
        0

        >>> T = ClusterQuiver(Q.digraph().edges(sort=True), frozen=[Integer(3)])
        >>> T.n()
        3
        >>> T.m()
        1

  mutate(data, inplace=True)

    Mutate `self` at a sequence of vertices.

    INPUT:

    - `sequence` – a vertex of `self`, an iterator of vertices of `self`, a function which takes in the ClusterQuiver and returns a vertex or an iterator of vertices, or a string of the parameter wanting to be called on `ClusterQuiver` that will return a vertex or an iterator of vertices

    - `inplace` – boolean (default: `True`); if `False`, the result is returned, otherwise `self` is modified

    EXAMPLES:

    Sage

        sage: Q = ClusterQuiver(['A',4]); Q.b_matrix()
        [ 0  1  0  0]
        [-1  0 -1  0]
        [ 0  1  0  1]
        [ 0  0 -1  0]

        sage: Q.mutate(0); Q.b_matrix()
        [ 0 -1  0  0]
        [ 1  0 -1  0]
        [ 0  1  0  1]
        [ 0  0 -1  0]

        sage: T = Q.mutate(0, inplace=False); T
        Quiver on 4 vertices of type ['A', 4]

        sage: Q.mutate(0)
        sage: Q == T
        True

        sage: Q.mutate([0,1,0])
        sage: Q.b_matrix()
        [ 0 -1  1  0]
        [ 1  0  0  0]
        [-1  0  0  1]
        [ 0  0 -1  0]

        sage: Q = ClusterQuiver(QuiverMutationType([['A',1],['A',3]]))
        sage: Q.b_matrix()
        [ 0  0  0  0]
        [ 0  0  1  0]
        [ 0 -1  0 -1]
        [ 0  0  1  0]

        sage: T = Q.mutate(0,inplace=False)
        sage: Q == T
        True

        sage: Q = ClusterQuiver(['A',3]); Q.b_matrix()
        [ 0  1  0]
        [-1  0 -1]
        [ 0  1  0]
        sage: Q.mutate('first_sink'); Q.b_matrix()
        [ 0 -1  0]
        [ 1  0  1]
        [ 0 -1  0]
        sage: Q.mutate('first_source'); Q.b_matrix()
        [ 0  1  0]
        [-1  0 -1]
        [ 0  1  0]

        sage: dg = DiGraph()
        sage: dg.add_vertices(['a','b','c','d','e'])
        sage: dg.add_edges([['a','b'], ['b','c'], ['c','d'], ['d','e']])
        sage: Q2 = ClusterQuiver(dg, frozen=['c']); Q2.b_matrix()
        [ 0  1  0  0]
        [-1  0  0  0]
        [ 0  0  0  1]
        [ 0  0 -1  0]
        [ 0 -1  1  0]
        sage: Q2.mutate('a'); Q2.b_matrix()
        [ 0 -1  0  0]
        [ 1  0  0  0]
        [ 0  0  0  1]
        [ 0  0 -1  0]
        [ 0 -1  1  0]

        sage: dg = DiGraph([['a', 'b'], ['b', 'c']], format='list_of_edges')
        sage: Q = ClusterQuiver(dg);Q
        Quiver on 3 vertices
        sage: Q.mutate(['a','b'],inplace=False).digraph().edges(sort=True)
        [('a', 'b', (1, -1)), ('c', 'b', (1, -1))]

    Python

        >>> from sage.all import *
        >>> Q = ClusterQuiver(['A',Integer(4)]); Q.b_matrix()
        [ 0  1  0  0]
        [-1  0 -1  0]
        [ 0  1  0  1]
        [ 0  0 -1  0]

        >>> Q.mutate(Integer(0)); Q.b_matrix()
        [ 0 -1  0  0]
        [ 1  0 -1  0]
        [ 0  1  0  1]
        [ 0  0 -1  0]

        >>> T = Q.mutate(Integer(0), inplace=False); T
        Quiver on 4 vertices of type ['A', 4]

        >>> Q.mutate(Integer(0))
        >>> Q == T
        True

        >>> Q.mutate([Integer(0),Integer(1),Integer(0)])
        >>> Q.b_matrix()
        [ 0 -1  1  0]
        [ 1  0  0  0]
        [-1  0  0  1]
        [ 0  0 -1  0]

        >>> Q = ClusterQuiver(QuiverMutationType([['A',Integer(1)],['A',Integer(3)]]))
        >>> Q.b_matrix()
        [ 0  0  0  0]
        [ 0  0  1  0]
        [ 0 -1  0 -1]
        [ 0  0  1  0]

        >>> T = Q.mutate(Integer(0),inplace=False)
        >>> Q == T
        True

        >>> Q = ClusterQuiver(['A',Integer(3)]); Q.b_matrix()
        [ 0  1  0]
        [-1  0 -1]
        [ 0  1  0]
        >>> Q.mutate('first_sink'); Q.b_matrix()
        [ 0 -1  0]
        [ 1  0  1]
        [ 0 -1  0]
        >>> Q.mutate('first_source'); Q.b_matrix()
        [ 0  1  0]
        [-1  0 -1]
        [ 0  1  0]

        >>> dg = DiGraph()
        >>> dg.add_vertices(['a','b','c','d','e'])
        >>> dg.add_edges([['a','b'], ['b','c'], ['c','d'], ['d','e']])
        >>> Q2 = ClusterQuiver(dg, frozen=['c']); Q2.b_matrix()
        [ 0  1  0  0]
        [-1  0  0  0]
        [ 0  0  0  1]
        [ 0  0 -1  0]
        [ 0 -1  1  0]
        >>> Q2.mutate('a'); Q2.b_matrix()
        [ 0 -1  0  0]
        [ 1  0  0  0]
        [ 0  0  0  1]
        [ 0  0 -1  0]
        [ 0 -1  1  0]

        >>> dg = DiGraph([['a', 'b'], ['b', 'c']], format='list_of_edges')
        >>> Q = ClusterQuiver(dg);Q
        Quiver on 3 vertices
        >>> Q.mutate(['a','b'],inplace=False).digraph().edges(sort=True)
        [('a', 'b', (1, -1)), ('c', 'b', (1, -1))]

  mutation_class(depth=+Infinity, show_depth=False, return_paths=False, data_type='quiver', up_to_equivalence=True, sink_source=False)

    Return the mutation class of `self` together with certain constraints.

    INPUT:

    - `depth` – (default: `infinity`) integer, only seeds with distance at most depth from `self` are returned

    - `show_depth` – boolean (default: `False`); if `True`, the actual depth of the mutation is shown

    - `return_paths` – boolean (default: `False`); if `True`, a shortest path of mutation sequences from `self` to the given quiver is returned as well

    - `data_type` – (default: `'quiver'`) can be one of the following:

      - `'quiver'` – the quiver is returned

      - `'dig6'` – the dig6-data is returned

      - `'path'` – shortest paths of mutation sequences from `self` are returned

    - `sink_source` – boolean (default: `False`); if `True`, only mutations at sinks and sources are applied

    EXAMPLES:

    Sage

        sage: Q = ClusterQuiver(['A',3])
        sage: Ts = Q.mutation_class()
        sage: for T in Ts: print(T)
        Quiver on 3 vertices of type ['A', 3]
        Quiver on 3 vertices of type ['A', 3]
        Quiver on 3 vertices of type ['A', 3]
        Quiver on 3 vertices of type ['A', 3]

        sage: Ts = Q.mutation_class(depth=1)
        sage: for T in Ts: print(T)
        Quiver on 3 vertices of type ['A', 3]
        Quiver on 3 vertices of type ['A', 3]
        Quiver on 3 vertices of type ['A', 3]

        sage: Ts = Q.mutation_class(show_depth=True)
        Depth: 0     found: 1          Time: ... s
        Depth: 1     found: 3          Time: ... s
        Depth: 2     found: 4          Time: ... s

        sage: Ts = Q.mutation_class(return_paths=True)
        sage: for T in Ts: print(T)
        (Quiver on 3 vertices of type ['A', 3], [])
        (Quiver on 3 vertices of type ['A', 3], [1])
        (Quiver on 3 vertices of type ['A', 3], [0])
        (Quiver on 3 vertices of type ['A', 3], [0, 1])

        sage: Ts = Q.mutation_class(up_to_equivalence=False)
        sage: for T in Ts: print(T)
        Quiver on 3 vertices of type ['A', 3]
        Quiver on 3 vertices of type ['A', 3]
        Quiver on 3 vertices of type ['A', 3]
        Quiver on 3 vertices of type ['A', 3]
        Quiver on 3 vertices of type ['A', 3]
        Quiver on 3 vertices of type ['A', 3]
        Quiver on 3 vertices of type ['A', 3]
        Quiver on 3 vertices of type ['A', 3]
        Quiver on 3 vertices of type ['A', 3]
        Quiver on 3 vertices of type ['A', 3]
        Quiver on 3 vertices of type ['A', 3]
        Quiver on 3 vertices of type ['A', 3]
        Quiver on 3 vertices of type ['A', 3]
        Quiver on 3 vertices of type ['A', 3]

        sage: Ts = Q.mutation_class(return_paths=True,up_to_equivalence=False)
        sage: len(Ts)
        14
        sage: Ts[0]
        (Quiver on 3 vertices of type ['A', 3], [])

        sage: Ts = Q.mutation_class(show_depth=True)
        Depth: 0     found: 1          Time: ... s
        Depth: 1     found: 3          Time: ... s
        Depth: 2     found: 4          Time: ... s

        sage: Ts = Q.mutation_class(show_depth=True, up_to_equivalence=False)
        Depth: 0     found: 1          Time: ... s
        Depth: 1     found: 4          Time: ... s
        Depth: 2     found: 6          Time: ... s
        Depth: 3     found: 10        Time: ... s
        Depth: 4     found: 14        Time: ... s

    Python

        >>> from sage.all import *
        >>> Q = ClusterQuiver(['A',Integer(3)])
        >>> Ts = Q.mutation_class()
        >>> for T in Ts: print(T)
        Quiver on 3 vertices of type ['A', 3]
        Quiver on 3 vertices of type ['A', 3]
        Quiver on 3 vertices of type ['A', 3]
        Quiver on 3 vertices of type ['A', 3]

        >>> Ts = Q.mutation_class(depth=Integer(1))
        >>> for T in Ts: print(T)
        Quiver on 3 vertices of type ['A', 3]
        Quiver on 3 vertices of type ['A', 3]
        Quiver on 3 vertices of type ['A', 3]

        >>> Ts = Q.mutation_class(show_depth=True)
        Depth: 0     found: 1          Time: ... s
        Depth: 1     found: 3          Time: ... s
        Depth: 2     found: 4          Time: ... s

        >>> Ts = Q.mutation_class(return_paths=True)
        >>> for T in Ts: print(T)
        (Quiver on 3 vertices of type ['A', 3], [])
        (Quiver on 3 vertices of type ['A', 3], [1])
        (Quiver on 3 vertices of type ['A', 3], [0])
        (Quiver on 3 vertices of type ['A', 3], [0, 1])

        >>> Ts = Q.mutation_class(up_to_equivalence=False)
        >>> for T in Ts: print(T)
        Quiver on 3 vertices of type ['A', 3]
        Quiver on 3 vertices of type ['A', 3]
        Quiver on 3 vertices of type ['A', 3]
        Quiver on 3 vertices of type ['A', 3]
        Quiver on 3 vertices of type ['A', 3]
        Quiver on 3 vertices of type ['A', 3]
        Quiver on 3 vertices of type ['A', 3]
        Quiver on 3 vertices of type ['A', 3]
        Quiver on 3 vertices of type ['A', 3]
        Quiver on 3 vertices of type ['A', 3]
        Quiver on 3 vertices of type ['A', 3]
        Quiver on 3 vertices of type ['A', 3]
        Quiver on 3 vertices of type ['A', 3]
        Quiver on 3 vertices of type ['A', 3]

        >>> Ts = Q.mutation_class(return_paths=True,up_to_equivalence=False)
        >>> len(Ts)
        14
        >>> Ts[Integer(0)]
        (Quiver on 3 vertices of type ['A', 3], [])

        >>> Ts = Q.mutation_class(show_depth=True)
        Depth: 0     found: 1          Time: ... s
        Depth: 1     found: 3          Time: ... s
        Depth: 2     found: 4          Time: ... s

        >>> Ts = Q.mutation_class(show_depth=True, up_to_equivalence=False)
        Depth: 0     found: 1          Time: ... s
        Depth: 1     found: 4          Time: ... s
        Depth: 2     found: 6          Time: ... s
        Depth: 3     found: 10        Time: ... s
        Depth: 4     found: 14        Time: ... s

  mutation_class_iter(depth=+Infinity, show_depth=False, return_paths=False, data_type='quiver', up_to_equivalence=True, sink_source=False)

    Return an iterator for the mutation class of `self` together with certain constraints.

    INPUT:

    - `depth` – integer (default: infinity); only quivers with distance at most depth from `self` are returned.

    - `show_depth` – boolean (default: `False`); if `True`, the actual depth of the mutation is shown

    - `return_paths` – boolean (default: `False`); if `True`, a shortest path of mutation sequences from `self` to the given quiver is returned as well

    - `data_type` – (default: `'quiver'`) can be one of the following:

          * "quiver"
          * "matrix"
          * "digraph"
          * "dig6"
          * "path"

    - `up_to_equivalence` – boolean (default: `True`); if `True`, only one quiver for each graph-isomorphism class is recorded

    - `sink_source` – boolean (default: `False`); if `True`, only mutations at sinks and sources are applied

    EXAMPLES:

    Sage

        sage: Q = ClusterQuiver(['A',3])
        sage: it = Q.mutation_class_iter()
        sage: for T in it: print(T)
        Quiver on 3 vertices of type ['A', 3]
        Quiver on 3 vertices of type ['A', 3]
        Quiver on 3 vertices of type ['A', 3]
        Quiver on 3 vertices of type ['A', 3]

        sage: it = Q.mutation_class_iter(depth=1)
        sage: for T in it: print(T)
        Quiver on 3 vertices of type ['A', 3]
        Quiver on 3 vertices of type ['A', 3]
        Quiver on 3 vertices of type ['A', 3]

        sage: it = Q.mutation_class_iter(show_depth=True)
        sage: for T in it: pass
        Depth: 0     found: 1          Time: ... s
        Depth: 1     found: 3          Time: ... s
        Depth: 2     found: 4          Time: ... s

        sage: it = Q.mutation_class_iter(return_paths=True)
        sage: for T in it: print(T)
        (Quiver on 3 vertices of type ['A', 3], [])
        (Quiver on 3 vertices of type ['A', 3], [1])
        (Quiver on 3 vertices of type ['A', 3], [0])
        (Quiver on 3 vertices of type ['A', 3], [0, 1])

        sage: it = Q.mutation_class_iter(up_to_equivalence=False)
        sage: for T in it: print(T)
        Quiver on 3 vertices of type ['A', 3]
        Quiver on 3 vertices of type ['A', 3]
        Quiver on 3 vertices of type ['A', 3]
        Quiver on 3 vertices of type ['A', 3]
        Quiver on 3 vertices of type ['A', 3]
        Quiver on 3 vertices of type ['A', 3]
        Quiver on 3 vertices of type ['A', 3]
        Quiver on 3 vertices of type ['A', 3]
        Quiver on 3 vertices of type ['A', 3]
        Quiver on 3 vertices of type ['A', 3]
        Quiver on 3 vertices of type ['A', 3]
        Quiver on 3 vertices of type ['A', 3]
        Quiver on 3 vertices of type ['A', 3]
        Quiver on 3 vertices of type ['A', 3]

        sage: it = Q.mutation_class_iter(return_paths=True,
        ....:        up_to_equivalence=False)
        sage: mutation_class = list(it)
        sage: len(mutation_class)
        14
        sage: mutation_class[0]
        (Quiver on 3 vertices of type ['A', 3], [])

        sage: Q = ClusterQuiver(['A',3])
        sage: it = Q.mutation_class_iter(data_type='path')
        sage: for T in it: print(T)
        []
        [1]
        [0]
        [0, 1]

        sage: Q = ClusterQuiver(['A',3])
        sage: it = Q.mutation_class_iter(return_paths=True,
        ....:        data_type='matrix')
        sage: next(it)
        (
        [ 0  0  1]
        [ 0  0  1]
        [-1 -1  0], []
        )

        sage: dg = DiGraph([['a', 'b'], ['b', 'c']],
        ....:        format='list_of_edges')
        sage: S = ClusterQuiver(dg, frozen=['b'])
        sage: S.mutation_class()
        [Quiver on 3 vertices with 1 frozen vertex,
         Quiver on 3 vertices with 1 frozen vertex,
         Quiver on 3 vertices with 1 frozen vertex]

    Python

        >>> from sage.all import *
        >>> Q = ClusterQuiver(['A',Integer(3)])
        >>> it = Q.mutation_class_iter()
        >>> for T in it: print(T)
        Quiver on 3 vertices of type ['A', 3]
        Quiver on 3 vertices of type ['A', 3]
        Quiver on 3 vertices of type ['A', 3]
        Quiver on 3 vertices of type ['A', 3]

        >>> it = Q.mutation_class_iter(depth=Integer(1))
        >>> for T in it: print(T)
        Quiver on 3 vertices of type ['A', 3]
        Quiver on 3 vertices of type ['A', 3]
        Quiver on 3 vertices of type ['A', 3]

        >>> it = Q.mutation_class_iter(show_depth=True)
        >>> for T in it: pass
        Depth: 0     found: 1          Time: ... s
        Depth: 1     found: 3          Time: ... s
        Depth: 2     found: 4          Time: ... s

        >>> it = Q.mutation_class_iter(return_paths=True)
        >>> for T in it: print(T)
        (Quiver on 3 vertices of type ['A', 3], [])
        (Quiver on 3 vertices of type ['A', 3], [1])
        (Quiver on 3 vertices of type ['A', 3], [0])
        (Quiver on 3 vertices of type ['A', 3], [0, 1])

        >>> it = Q.mutation_class_iter(up_to_equivalence=False)
        >>> for T in it: print(T)
        Quiver on 3 vertices of type ['A', 3]
        Quiver on 3 vertices of type ['A', 3]
        Quiver on 3 vertices of type ['A', 3]
        Quiver on 3 vertices of type ['A', 3]
        Quiver on 3 vertices of type ['A', 3]
        Quiver on 3 vertices of type ['A', 3]
        Quiver on 3 vertices of type ['A', 3]
        Quiver on 3 vertices of type ['A', 3]
        Quiver on 3 vertices of type ['A', 3]
        Quiver on 3 vertices of type ['A', 3]
        Quiver on 3 vertices of type ['A', 3]
        Quiver on 3 vertices of type ['A', 3]
        Quiver on 3 vertices of type ['A', 3]
        Quiver on 3 vertices of type ['A', 3]

        >>> it = Q.mutation_class_iter(return_paths=True,
        ...        up_to_equivalence=False)
        >>> mutation_class = list(it)
        >>> len(mutation_class)
        14
        >>> mutation_class[Integer(0)]
        (Quiver on 3 vertices of type ['A', 3], [])

        >>> Q = ClusterQuiver(['A',Integer(3)])
        >>> it = Q.mutation_class_iter(data_type='path')
        >>> for T in it: print(T)
        []
        [1]
        [0]
        [0, 1]

        >>> Q = ClusterQuiver(['A',Integer(3)])
        >>> it = Q.mutation_class_iter(return_paths=True,
        ...        data_type='matrix')
        >>> next(it)
        (
        [ 0  0  1]
        [ 0  0  1]
        [-1 -1  0], []
        )

        >>> dg = DiGraph([['a', 'b'], ['b', 'c']],
        ...        format='list_of_edges')
        >>> S = ClusterQuiver(dg, frozen=['b'])
        >>> S.mutation_class()
        [Quiver on 3 vertices with 1 frozen vertex,
         Quiver on 3 vertices with 1 frozen vertex,
         Quiver on 3 vertices with 1 frozen vertex]

  mutation_sequence(sequence, show_sequence=False, fig_size=1.2)

    Return a list containing the sequence of quivers obtained from `self` by a sequence of mutations on vertices.

    INPUT:

    - `sequence` – list or tuple of vertices of `self`

    - `show_sequence` – boolean (default: `False`); if `True`, a png containing the mutation sequence is shown

    - `fig_size` – (default: 1.2) factor by which the size of the sequence is expanded

    EXAMPLES:

    Sage

        sage: Q = ClusterQuiver(['A',4])
        sage: seq = Q.mutation_sequence([0,1]); seq
        [Quiver on 4 vertices of type ['A', 4],
         Quiver on 4 vertices of type ['A', 4],
         Quiver on 4 vertices of type ['A', 4]]
        sage: [T.b_matrix() for T in seq]
        [
        [ 0  1  0  0]  [ 0 -1  0  0]  [ 0  1 -1  0]
        [-1  0 -1  0]  [ 1  0 -1  0]  [-1  0  1  0]
        [ 0  1  0  1]  [ 0  1  0  1]  [ 1 -1  0  1]
        [ 0  0 -1  0], [ 0  0 -1  0], [ 0  0 -1  0]
        ]

    Python

        >>> from sage.all import *
        >>> Q = ClusterQuiver(['A',Integer(4)])
        >>> seq = Q.mutation_sequence([Integer(0),Integer(1)]); seq
        [Quiver on 4 vertices of type ['A', 4],
         Quiver on 4 vertices of type ['A', 4],
         Quiver on 4 vertices of type ['A', 4]]
        >>> [T.b_matrix() for T in seq]
        [
        [ 0  1  0  0]  [ 0 -1  0  0]  [ 0  1 -1  0]
        [-1  0 -1  0]  [ 1  0 -1  0]  [-1  0  1  0]
        [ 0  1  0  1]  [ 0  1  0  1]  [ 1 -1  0  1]
        [ 0  0 -1  0], [ 0  0 -1  0], [ 0  0 -1  0]
        ]

  mutation_type()

    Return the mutation type of `self`.

    Return the mutation_type of each connected component of `self` if it can be determined, otherwise, the mutation type of this component is set to be unknown.

    The mutation types of the components are ordered by vertex labels.

    If you do many type recognitions, you should consider to save exceptional mutation types using `save_quiver_data()`

    WARNING:

    - All finite types can be detected,

    - All affine types can be detected, EXCEPT affine type D (the algorithm is not yet implemented)

    - All exceptional types can be detected.

    EXAMPLES:

    Sage

        sage: ClusterQuiver(['A',4]).mutation_type()
        ['A', 4]
        sage: ClusterQuiver(['A',(3,1),1]).mutation_type()
        ['A', [1, 3], 1]
        sage: ClusterQuiver(['C',2]).mutation_type()
        ['B', 2]
        sage: ClusterQuiver(['B',4,1]).mutation_type()
        ['BD', 4, 1]

    Python

        >>> from sage.all import *
        >>> ClusterQuiver(['A',Integer(4)]).mutation_type()
        ['A', 4]
        >>> ClusterQuiver(['A',(Integer(3),Integer(1)),Integer(1)]).mutation_type()
        ['A', [1, 3], 1]
        >>> ClusterQuiver(['C',Integer(2)]).mutation_type()
        ['B', 2]
        >>> ClusterQuiver(['B',Integer(4),Integer(1)]).mutation_type()
        ['BD', 4, 1]

    finite types:

    Sage

        sage: Q = ClusterQuiver(['A',5])
        sage: Q._mutation_type = None
        sage: Q.mutation_type()
        ['A', 5]

        sage: Q = ClusterQuiver([(0,1),(1,2),(2,3),(3,4)])
        sage: Q.mutation_type()
        ['A', 5]

        sage: Q = ClusterQuiver(DiGraph([['a', 'b'], ['c', 'b'], ['c', 'd'], ['e', 'd']]),
        ....:                   frozen=['c'])
        sage: Q.mutation_type()
        [ ['A', 2], ['A', 2] ]

    [Python]

        >>> from sage.all import *
        >>> Q = ClusterQuiver(['A',Integer(5)])
        >>> Q._mutation_type = None
        >>> Q.mutation_type()
        ['A', 5]

        >>> Q = ClusterQuiver([(Integer(0),Integer(1)),(Integer(1),Integer(2)),(Integer(2),Integer(3)),(Integer(3),Integer(4))])
        >>> Q.mutation_type()
        ['A', 5]

        >>> Q = ClusterQuiver(DiGraph([['a', 'b'], ['c', 'b'], ['c', 'd'], ['e', 'd']]),
        ...                   frozen=['c'])
        >>> Q.mutation_type()
        [ ['A', 2], ['A', 2] ]

    affine types:

    Sage

        sage: Q = ClusterQuiver(['E',8,[1,1]]); Q
        Quiver on 10 vertices of type ['E', 8, [1, 1]]
        sage: Q._mutation_type = None; Q
        Quiver on 10 vertices
        sage: Q.mutation_type() # long time
        ['E', 8, [1, 1]]

    Python

        >>> from sage.all import *
        >>> Q = ClusterQuiver(['E',Integer(8),[Integer(1),Integer(1)]]); Q
        Quiver on 10 vertices of type ['E', 8, [1, 1]]
        >>> Q._mutation_type = None; Q
        Quiver on 10 vertices
        >>> Q.mutation_type() # long time
        ['E', 8, [1, 1]]

    the not yet working affine type D (unless user has saved small classical quiver data):

    Sage

        sage: Q = ClusterQuiver(['D',4,1])
        sage: Q._mutation_type = None
        sage: Q.mutation_type() # todo: not implemented
        ['D', 4, 1]

    [Python]

        >>> from sage.all import *
        >>> Q = ClusterQuiver(['D',Integer(4),Integer(1)])
        >>> Q._mutation_type = None
        >>> Q.mutation_type() # todo: not implemented
        ['D', 4, 1]

    the exceptional types:

    Sage

        sage: Q = ClusterQuiver(['X',6])
        sage: Q._mutation_type = None
        sage: Q.mutation_type() # long time
        ['X', 6]

    Python

        >>> from sage.all import *
        >>> Q = ClusterQuiver(['X',Integer(6)])
        >>> Q._mutation_type = None
        >>> Q.mutation_type() # long time
        ['X', 6]

    examples from page 8 of [Ke2008]:

    Sage

        sage: dg = DiGraph(); dg.add_edges([(9,0),(9,4),(4,6),(6,7),(7,8),(8,3),(3,5),(5,6),(8,1),(2,3)])
        sage: ClusterQuiver(dg).mutation_type() # long time
        ['E', 8, [1, 1]]

        sage: dg = DiGraph({ 0:[3], 1:[0,4], 2:[0,6], 3:[1,2,7], 4:[3,8], 5:[2], 6:[3,5], 7:[4,6], 8:[7] })
        sage: ClusterQuiver(dg).mutation_type() # long time
        ['E', 8, 1]

        sage: dg = DiGraph({ 0:[3,9], 1:[0,4], 2:[0,6], 3:[1,2,7], 4:[3,8], 5:[2], 6:[3,5], 7:[4,6], 8:[7], 9:[1] })
        sage: ClusterQuiver(dg).mutation_type() # long time
        ['E', 8, [1, 1]]

    [Python]

        >>> from sage.all import *
        >>> dg = DiGraph(); dg.add_edges([(Integer(9),Integer(0)),(Integer(9),Integer(4)),(Integer(4),Integer(6)),(Integer(6),Integer(7)),(Integer(7),Integer(8)),(Integer(8),Integer(3)),(Integer(3),Integer(5)),(Integer(5),Integer(6)),(Integer(8),Integer(1)),(Integer(2),Integer(3))])
        >>> ClusterQuiver(dg).mutation_type() # long time
        ['E', 8, [1, 1]]

        >>> dg = DiGraph({ Integer(0):[Integer(3)], Integer(1):[Integer(0),Integer(4)], Integer(2):[Integer(0),Integer(6)], Integer(3):[Integer(1),Integer(2),Integer(7)], Integer(4):[Integer(3),Integer(8)], Integer(5):[Integer(2)], Integer(6):[Integer(3),Integer(5)], Integer(7):[Integer(4),Integer(6)], Integer(8):[Integer(7)] })
        >>> ClusterQuiver(dg).mutation_type() # long time
        ['E', 8, 1]

        >>> dg = DiGraph({ Integer(0):[Integer(3),Integer(9)], Integer(1):[Integer(0),Integer(4)], Integer(2):[Integer(0),Integer(6)], Integer(3):[Integer(1),Integer(2),Integer(7)], Integer(4):[Integer(3),Integer(8)], Integer(5):[Integer(2)], Integer(6):[Integer(3),Integer(5)], Integer(7):[Integer(4),Integer(6)], Integer(8):[Integer(7)], Integer(9):[Integer(1)] })
        >>> ClusterQuiver(dg).mutation_type() # long time
        ['E', 8, [1, 1]]

    infinite types:

    Sage

        sage: Q = ClusterQuiver(['GR',[4,9]])
        sage: Q._mutation_type = None
        sage: Q.mutation_type()
        'undetermined infinite mutation type'

    Python

        >>> from sage.all import *
        >>> Q = ClusterQuiver(['GR',[Integer(4),Integer(9)]])
        >>> Q._mutation_type = None
        >>> Q.mutation_type()
        'undetermined infinite mutation type'

    reducible types:

    Sage

        sage: Q = ClusterQuiver([['A', 3], ['B', 3]])
        sage: Q._mutation_type = None
        sage: Q.mutation_type()
        [ ['A', 3], ['B', 3] ]

        sage: Q = ClusterQuiver([['A', 3], ['T', [4,4,4]]])
        sage: Q._mutation_type = None
        sage: Q.mutation_type()
        [['A', 3], 'undetermined infinite mutation type']

        sage: Q = ClusterQuiver([['A', 3], ['B', 3], ['T', [4,4,4]]])
        sage: Q._mutation_type = None
        sage: Q.mutation_type()
        [['A', 3], ['B', 3], 'undetermined infinite mutation type']

        sage: Q = ClusterQuiver([[0,1,2],[1,2,2],[2,0,2],[3,4,1],[4,5,1]])
        sage: Q.mutation_type()
        ['undetermined finite mutation type', ['A', 3]]

    [Python]

        >>> from sage.all import *
        >>> Q = ClusterQuiver([['A', Integer(3)], ['B', Integer(3)]])
        >>> Q._mutation_type = None
        >>> Q.mutation_type()
        [ ['A', 3], ['B', 3] ]

        >>> Q = ClusterQuiver([['A', Integer(3)], ['T', [Integer(4),Integer(4),Integer(4)]]])
        >>> Q._mutation_type = None
        >>> Q.mutation_type()
        [['A', 3], 'undetermined infinite mutation type']

        >>> Q = ClusterQuiver([['A', Integer(3)], ['B', Integer(3)], ['T', [Integer(4),Integer(4),Integer(4)]]])
        >>> Q._mutation_type = None
        >>> Q.mutation_type()
        [['A', 3], ['B', 3], 'undetermined infinite mutation type']

        >>> Q = ClusterQuiver([[Integer(0),Integer(1),Integer(2)],[Integer(1),Integer(2),Integer(2)],[Integer(2),Integer(0),Integer(2)],[Integer(3),Integer(4),Integer(1)],[Integer(4),Integer(5),Integer(1)]])
        >>> Q.mutation_type()
        ['undetermined finite mutation type', ['A', 3]]

  n()

    Return the number of free vertices of `self`.

    EXAMPLES:

    Sage

        sage: ClusterQuiver(['A',4]).n()
        4
        sage: ClusterQuiver(['A',(3,1),1]).n()
        4
        sage: ClusterQuiver(['B',4]).n()
        4
        sage: ClusterQuiver(['B',4,1]).n()
        5

    Python

        >>> from sage.all import *
        >>> ClusterQuiver(['A',Integer(4)]).n()
        4
        >>> ClusterQuiver(['A',(Integer(3),Integer(1)),Integer(1)]).n()
        4
        >>> ClusterQuiver(['B',Integer(4)]).n()
        4
        >>> ClusterQuiver(['B',Integer(4),Integer(1)]).n()
        5

  number_of_edges()

    Return the total number of edges on the quiver.

    Note

    This only works with non-valued quivers. If used on a non-valued quiver then the positive value is taken to be the number of edges added.

    OUTPUT: integer of the number of edges

    EXAMPLES:

    Sage

        sage: S = ClusterQuiver(['A',4]); S.number_of_edges()
        3

        sage: S = ClusterQuiver(['B',4]); S.number_of_edges()
        3

    Python

        >>> from sage.all import *
        >>> S = ClusterQuiver(['A',Integer(4)]); S.number_of_edges()
        3

        >>> S = ClusterQuiver(['B',Integer(4)]); S.number_of_edges()
        3

  plot(circular=True, center=(0, 0), directed=True, mark=None, save_pos=False, greens=[])

    Return the plot of the underlying digraph of `self`.

    INPUT:

    - `circular` – boolean (default: `True`); if `True`, the circular plot is chosen, otherwise >>spring<< is used

    - `center` – (default: (0,0)) sets the center of the circular plot, otherwise it is ignored

    - `directed` – boolean (default: `True`); if `True`, the directed version is shown, otherwise the undirected

    - `mark` – (default: `None`) if set to i, the vertex i is highlighted

    - `save_pos` – boolean (default: `False`); if `True`, the positions of the vertices are saved

    - `greens` – (default: `[]`) if set to a list, will display the green vertices as green

    EXAMPLES:

    Sage

        sage: Q = ClusterQuiver(['A',5])
        sage: Q.plot()                                                              # needs sage.plot sage.symbolic
        Graphics object consisting of 15 graphics primitives
        sage: Q.plot(circular=True)                                                 # needs sage.plot sage.symbolic
        Graphics object consisting of 15 graphics primitives
        sage: Q.plot(circular=True, mark=1)                                         # needs sage.plot sage.symbolic
        Graphics object consisting of 15 graphics primitives

    Python

        >>> from sage.all import *
        >>> Q = ClusterQuiver(['A',Integer(5)])
        >>> Q.plot()                                                              # needs sage.plot sage.symbolic
        Graphics object consisting of 15 graphics primitives
        >>> Q.plot(circular=True)                                                 # needs sage.plot sage.symbolic
        Graphics object consisting of 15 graphics primitives
        >>> Q.plot(circular=True, mark=Integer(1))                                         # needs sage.plot sage.symbolic
        Graphics object consisting of 15 graphics primitives

  poincare_semistable(theta, d)

    Return the Poincaré polynomial of the moduli space of semi-stable representations of dimension vector \(d\).

    INPUT:

    - `theta` – stability weight, as list or vector of rationals

    - `d` – dimension vector, as list or vector of coprime integers

    The semi-stability is taken with respect to the slope function

    \[\mu(d) = \theta(d) / \operatorname{dim}(d)\]

    where \(d\) is a dimension vector.

    This uses the matrix-inversion algorithm from [Rei2002].

    EXAMPLES:

    Sage

        sage: Q = ClusterQuiver(['A',2])
        sage: Q.poincare_semistable([1,0],[1,0])
        1
        sage: Q.poincare_semistable([1,0],[1,1])
        1

        sage: K2 = ClusterQuiver(matrix([[0,2],[-2,0]]))
        sage: theta = (1, 0)
        sage: K2.poincare_semistable(theta, [1,0])
        1
        sage: K2.poincare_semistable(theta, [1,1])
        v^2 + 1
        sage: K2.poincare_semistable(theta, [1,2])
        1
        sage: K2.poincare_semistable(theta, [1,3])
        0

        sage: K3 = ClusterQuiver(matrix([[0,3],[-3,0]]))
        sage: theta = (1, 0)
        sage: K3.poincare_semistable(theta, (2,3))
        v^12 + v^10 + 3*v^8 + 3*v^6 + 3*v^4 + v^2 + 1
        sage: K3.poincare_semistable(theta, (3,4))(1)
        68

    Python

        >>> from sage.all import *
        >>> Q = ClusterQuiver(['A',Integer(2)])
        >>> Q.poincare_semistable([Integer(1),Integer(0)],[Integer(1),Integer(0)])
        1
        >>> Q.poincare_semistable([Integer(1),Integer(0)],[Integer(1),Integer(1)])
        1

        >>> K2 = ClusterQuiver(matrix([[Integer(0),Integer(2)],[-Integer(2),Integer(0)]]))
        >>> theta = (Integer(1), Integer(0))
        >>> K2.poincare_semistable(theta, [Integer(1),Integer(0)])
        1
        >>> K2.poincare_semistable(theta, [Integer(1),Integer(1)])
        v^2 + 1
        >>> K2.poincare_semistable(theta, [Integer(1),Integer(2)])
        1
        >>> K2.poincare_semistable(theta, [Integer(1),Integer(3)])
        0

        >>> K3 = ClusterQuiver(matrix([[Integer(0),Integer(3)],[-Integer(3),Integer(0)]]))
        >>> theta = (Integer(1), Integer(0))
        >>> K3.poincare_semistable(theta, (Integer(2),Integer(3)))
        v^12 + v^10 + 3*v^8 + 3*v^6 + 3*v^4 + v^2 + 1
        >>> K3.poincare_semistable(theta, (Integer(3),Integer(4)))(Integer(1))
        68

    REFERENCES:

    [Rei2002]

    Markus Reineke, The Harder-Narasimhan system in quantum groups and cohomology of quiver moduli, arXiv math/0204059

  principal_extension(inplace=False)

    Return the principal extension of `self`, adding n frozen vertices to any previously frozen vertices.

    This is the quiver obtained by adding an outgoing edge to every mutable vertex of `self`.

    EXAMPLES:

    Sage

        sage: Q = ClusterQuiver(['A',2]); Q
        Quiver on 2 vertices of type ['A', 2]
        sage: T = Q.principal_extension(); T
        Quiver on 4 vertices of type ['A', 2] with 2 frozen vertices
        sage: T2 = T.principal_extension(); T2
        Quiver on 6 vertices of type ['A', 2] with 4 frozen vertices
        sage: Q.digraph().edges(sort=True)
        [(0, 1, (1, -1))]
        sage: T.digraph().edges(sort=True)
        [(0, 1, (1, -1)), (2, 0, (1, -1)), (3, 1, (1, -1))]
        sage: T2.digraph().edges(sort=True)
        [(0, 1, (1, -1)), (2, 0, (1, -1)), (3, 1, (1, -1)),
         (4, 0, (1, -1)), (5, 1, (1, -1))]

    Python

        >>> from sage.all import *
        >>> Q = ClusterQuiver(['A',Integer(2)]); Q
        Quiver on 2 vertices of type ['A', 2]
        >>> T = Q.principal_extension(); T
        Quiver on 4 vertices of type ['A', 2] with 2 frozen vertices
        >>> T2 = T.principal_extension(); T2
        Quiver on 6 vertices of type ['A', 2] with 4 frozen vertices
        >>> Q.digraph().edges(sort=True)
        [(0, 1, (1, -1))]
        >>> T.digraph().edges(sort=True)
        [(0, 1, (1, -1)), (2, 0, (1, -1)), (3, 1, (1, -1))]
        >>> T2.digraph().edges(sort=True)
        [(0, 1, (1, -1)), (2, 0, (1, -1)), (3, 1, (1, -1)),
         (4, 0, (1, -1)), (5, 1, (1, -1))]

  qmu_save(filename=None)

    Save `self` in a `.qmu` file.

    This file can then be opened in Bernhard Keller’s Quiver Applet.

    See https://webusers.imj-prg.fr/~bernhard.keller/quivermutation/

    INPUT:

    - `filename` – the filename the image is saved to

    If a filename is not specified, the default name is `from_sage.qmu` in the current sage directory.

    EXAMPLES:

    Sage

        sage: Q = ClusterQuiver(['F',4,[1,2]])
        sage: import tempfile
        sage: with tempfile.NamedTemporaryFile(suffix='.qmu') as f:                 # needs sage.plot sage.symbolic
        ....:     Q.qmu_save(f.name)

    Python

        >>> from sage.all import *
        >>> Q = ClusterQuiver(['F',Integer(4),[Integer(1),Integer(2)]])
        >>> import tempfile
        >>> with tempfile.NamedTemporaryFile(suffix='.qmu') as f:                 # needs sage.plot sage.symbolic
        ...     Q.qmu_save(f.name)

    Make sure we can save quivers with \(m != n\) frozen variables, see Issue #14851:

    Sage

        sage: S = ClusterSeed(['A',3])
        sage: T1 = S.principal_extension()
        sage: Q = T1.quiver()
        sage: import tempfile
        sage: with tempfile.NamedTemporaryFile(suffix='.qmu') as f:                 # needs sage.plot sage.symbolic
        ....:     Q.qmu_save(f.name)

    [Python]

        >>> from sage.all import *
        >>> S = ClusterSeed(['A',Integer(3)])
        >>> T1 = S.principal_extension()
        >>> Q = T1.quiver()
        >>> import tempfile
        >>> with tempfile.NamedTemporaryFile(suffix='.qmu') as f:                 # needs sage.plot sage.symbolic
        ...     Q.qmu_save(f.name)

  relabel(relabelling, inplace=True)

    Return the quiver after doing a relabelling.

    Will relabel the vertices of the quiver.

    INPUT:

    - `relabelling` – dictionary of labels to move around

    - `inplace` – boolean (default: `True`); if `True`, will return a duplicate of the quiver

    EXAMPLES:

    Sage

        sage: S = ClusterQuiver(['A',4]).relabel({1:'5',2:'go'})

    Python

        >>> from sage.all import *
        >>> S = ClusterQuiver(['A',Integer(4)]).relabel({Integer(1):'5',Integer(2):'go'})

  reorient(data)

    Reorient `self` with respect to the given total order, or with respect to an iterator of edges in `self` to be reverted.

    Warning

    This operation might change the mutation type of `self`.

    INPUT:

    - `data` – an iterator defining a total order on `self.vertices()`, or an iterator of edges in `self` to be reoriented.

    EXAMPLES:

    Sage

        sage: Q = ClusterQuiver(['A',(2,3),1])
        sage: Q.mutation_type()
        ['A', [2, 3], 1]

        sage: Q.reorient([(0,1),(1,2),(2,3),(3,4)])
        sage: Q.mutation_type()
        ['D', 5]

        sage: Q.reorient([0,1,2,3,4])
        sage: Q.mutation_type()
        ['A', [1, 4], 1]

    Python

        >>> from sage.all import *
        >>> Q = ClusterQuiver(['A',(Integer(2),Integer(3)),Integer(1)])
        >>> Q.mutation_type()
        ['A', [2, 3], 1]

        >>> Q.reorient([(Integer(0),Integer(1)),(Integer(1),Integer(2)),(Integer(2),Integer(3)),(Integer(3),Integer(4))])
        >>> Q.mutation_type()
        ['D', 5]

        >>> Q.reorient([Integer(0),Integer(1),Integer(2),Integer(3),Integer(4)])
        >>> Q.mutation_type()
        ['A', [1, 4], 1]

  save_image(filename, circular=False)

    Save the plot of the underlying digraph of `self`.

    INPUT:

    - `filename` – the filename the image is saved to

    - `circular` – boolean (default: `False`); if `True`, the circular plot is chosen, otherwise >>spring<< is used

    EXAMPLES:

    Sage

        sage: Q = ClusterQuiver(['F',4,[1,2]])
        sage: import tempfile
        sage: with tempfile.NamedTemporaryFile(suffix='.png') as f:                 # needs sage.plot sage.symbolic
        ....:     Q.save_image(f.name)

    Python

        >>> from sage.all import *
        >>> Q = ClusterQuiver(['F',Integer(4),[Integer(1),Integer(2)]])
        >>> import tempfile
        >>> with tempfile.NamedTemporaryFile(suffix='.png') as f:                 # needs sage.plot sage.symbolic
        ...     Q.save_image(f.name)

  show(fig_size=1, circular=False, directed=True, mark=None, save_pos=False, greens=[])

    Show the plot of the underlying digraph of `self`.

    INPUT:

    - `fig_size` – (default: 1) factor by which the size of the plot is multiplied

    - `circular` – boolean (default: `False`); if `True`, the circular plot is chosen, otherwise >>spring<< is used

    - `directed` – boolean (default: `True`); if `True`, the directed version is shown, otherwise the undirected

    - `mark` – boolean (default: `None`); if set to i, the vertex i is highlighted

    - `save_pos` – boolean (default: `False`); if `True`, the positions of the vertices are saved

    - `greens` – (default: `[]`) if set to a list, will display the green vertices as green

  sinks()

    Return all vertices of `self` that are sinks.

    EXAMPLES:

    Sage

        sage: Q = ClusterQuiver(['A',5])
        sage: Q.mutate([1,2,4,3,2])
        sage: Q.sinks()
        [0, 2]

        sage: Q = ClusterQuiver(['A',5])
        sage: Q.mutate([2,1,3,4,2])
        sage: Q.sinks()
        [3]

    Python

        >>> from sage.all import *
        >>> Q = ClusterQuiver(['A',Integer(5)])
        >>> Q.mutate([Integer(1),Integer(2),Integer(4),Integer(3),Integer(2)])
        >>> Q.sinks()
        [0, 2]

        >>> Q = ClusterQuiver(['A',Integer(5)])
        >>> Q.mutate([Integer(2),Integer(1),Integer(3),Integer(4),Integer(2)])
        >>> Q.sinks()
        [3]

  sources()

    Return all vertices of `self` that are sources.

    EXAMPLES:

    Sage

        sage: Q = ClusterQuiver(['A',5])
        sage: Q.mutate([1,2,4,3,2])
        sage: Q.sources()
        []

        sage: Q = ClusterQuiver(['A',5])
        sage: Q.mutate([2,1,3,4,2])
        sage: Q.sources()
        [1]

    Python

        >>> from sage.all import *
        >>> Q = ClusterQuiver(['A',Integer(5)])
        >>> Q.mutate([Integer(1),Integer(2),Integer(4),Integer(3),Integer(2)])
        >>> Q.sources()
        []

        >>> Q = ClusterQuiver(['A',Integer(5)])
        >>> Q.mutate([Integer(2),Integer(1),Integer(3),Integer(4),Integer(2)])
        >>> Q.sources()
        [1]