Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
r""" Quiver mutation types
AUTHORS:
- Gregg Musiker (2012, initial version) - Christian Stump (2012, initial version) - Hugh Thomas (2012, initial version) """ #***************************************************************************** # Copyright (C) 2011 Gregg Musiker <gmusiker@gmail.com> # Christian Stump <christian.stump@gmail.com> # Hugh Thomas <hugh@math.unb.ca> # # Distributed under the terms of the GNU General Public License (GPL) # http://www.gnu.org/licenses/ #***************************************************************************** # python3
""" For a detailed description, see :meth:`QuiverMutationType`.
EXAMPLES::
sage: from sage.combinat.cluster_algebra_quiver.quiver_mutation_type import QuiverMutationTypeFactory sage: QuiverMutationTypeFactory() QuiverMutationType """ # get data as arguments or as list/tuple else:
# data is a QuiverMutationType return data
# check that data is a tuple or list else: _mutation_type_error( data )
# check for reducible types else:
# check for irreducible types else: _mutation_type_error(data)
# mutation type casting pass data = ('A',3,None) else: data = (data[0],(max(data[1])-min(data[1]),max(data[1])),data[2]) data = ('E',8,[1,1]) data = ('E',7,[1,1]) data = ('A',1,None) # mutation type casting from Kac conventions data = ('CC',2,1) if data[1] == 2: data = ('BB',2,1) elif data[1] > 2: data= ('CD',data[1],1) data = ('BB',data[1],1) # We think of ('A',3,2) as ('D',3,2) data = ('E',7,1)
# setting the parameters and returning the mutation type _mutation_type_error(data) rank = tuple(rank) twist = tuple(twist)
""" Return the string representation of ``self``.
EXAMPLES::
sage: QuiverMutationType # indirect doctest QuiverMutationType """
mutation_finite=None): """ Return a sample of the available quiver mutations types.
INPUT:
- ``finite``
- ``affine``
- ``elliptic``
- ``mutation_finite``
All four input keywords default values are ``None``. If set to ``True`` or ``False``, only these samples are returned.
EXAMPLES::
sage: QuiverMutationType.samples() [['A', 1], ['A', 5], ['B', 2], ['B', 5], ['C', 3], ['C', 5], [ ['A', 1], ['A', 1] ], ['D', 5], ['E', 6], ['E', 7], ['E', 8], ['F', 4], ['G', 2], ['A', [1, 1], 1], ['A', [4, 5], 1], ['D', 4, 1], ['BB', 5, 1], ['E', 6, [1, 1]], ['E', 7, [1, 1]], ['R2', [1, 5]], ['R2', [3, 5]], ['E', 10], ['BE', 5], ['GR', [3, 10]], ['T', [3, 3, 4]]]
sage: QuiverMutationType.samples(finite=True) [['A', 1], ['A', 5], ['B', 2], ['B', 5], ['C', 3], ['C', 5], [ ['A', 1], ['A', 1] ], ['D', 5], ['E', 6], ['E', 7], ['E', 8], ['F', 4], ['G', 2]]
sage: QuiverMutationType.samples(affine=True) [['A', [1, 1], 1], ['A', [4, 5], 1], ['D', 4, 1], ['BB', 5, 1]]
sage: QuiverMutationType.samples(elliptic=True) [['E', 6, [1, 1]], ['E', 7, [1, 1]]]
sage: QuiverMutationType.samples(mutation_finite=False) [['R2', [1, 5]], ['R2', [3, 5]], ['E', 10], ['BE', 5], ['GR', [3, 10]], ['T', [3, 3, 4]]] """ if t.is_mutation_finite() == mutation_finite]
def _samples(self): """ Return a list of sample of available Cartan types.
EXAMPLES::
sage: X = QuiverMutationType._samples() """ [QuiverMutationType(t) for t in [['A', 1], ['A', 5], ['B', 2], ['B', 5], ['C', 3], ['C', 5], ['D', 2], ['D', 5], ["E", 6], ["E", 7], ["E", 8], ["F", 4], ["G", 2]]] [QuiverMutationType(t) for t in [['A', [1,1], 1], ['A', [4,5], 1], ['D', 4, 1], ['BB', 5, 1]]] [QuiverMutationType(t) for t in [['E', 6, [1,1]], ['E', 7, [1,1]]]] [QuiverMutationType(t) for t in [['R2',(1,5)], ['R2',(3,5)]]] [QuiverMutationType(t) for t in [['E',10], ['BE',5], ['GR',(3,10)], ['T',(3,3,4)]]]
r"""
*Quiver mutation types* can be seen as a slight generalization of *generalized Cartan types*.
Background on generalized Cartan types can be found at
:wikipedia:`Generalized_Cartan_matrix`
For the compendium on the cluster algebra and quiver package in Sage see [MS2011]_
A `B`-matrix is a skew-symmetrizable `( n \times n )`-matrix `M`. I.e., there exists an invertible diagonal matrix `D` such that `DM` is skew-symmetric. `M` can be encoded as a *quiver* by having a directed edge from vertex `i` to vertex `j` with label `(a,b)` if `a = M_{i,j} > 0` and `b = M_{j,i} < 0`. We consider quivers up to *mutation equivalence*.
To a quiver mutation type we can associate a *generalized Cartan type* by sending `M` to the generalized Cartan matrix `C(M)` obtained by replacing all positive entries by their negatives and adding `2`'s on the main diagonal.
``QuiverMutationType`` constructs a quiver mutation type object. For more detail on the possible different types, please see the compendium.
INPUT:
The input consists either of a quiver mutation type, or of a ``letter`` (a string), a ``rank`` (one integer or a list/tuple of integers), and an optional ``twist`` (an integer or a list of integers). There are several different naming conventions for quiver mutation types.
- Finite type -- ``letter`` is a Dynkin type (A-G), and ``rank`` is the rank.
- Affine type -- there is more than one convention for naming affine types.
* Kac's notation: ``letter`` is a Dynkin type, ``rank`` is the rank of the associated finite Dynkin diagram, and ``twist`` is the twist, which could be 1, 2, or 3. In the special case of affine type A, there is more than one quiver mutation type associated to the Cartan type. In this case only, ``rank`` is a pair of integers (i,j), giving the number of edges pointing clockwise and the number of edges pointing counter-clockwise. The total number of vertices is given by i+j in this case.
* Naive notation: ``letter`` is one of 'BB', 'BC', 'BD', 'CC', 'CD'. The name specifies the two ends of the diagram, which are joined by a path. The total number of vertices is given by ``rank +1`` (to match the indexing people expect because these are affine types). In general, ``rank`` must be large enough for the picture to make sense, but we accept ``letter`` is ``BC`` and ``rank=1``.
* Macdonald notation: for the dual of an untwisted affine type (such as ['C', 6,1]), we accept a twist of -1 (i.e., ['C',6,-1]).
- Elliptic type -- ``letter`` is a Dynkin type, ``rank`` is the rank of the finite Dynkin diagram, and ``twist`` is a tuple of two integers. We follow Saito's notation.
- Other shapes:
* Rank 2: ``letter`` is 'R2', and ``rank`` is a pair of integers specifying the label on the unique edge.
* Triangle: ``letter`` is ``TR``, and ``rank`` is the number of vertices along a side.
* T: This defines a quiver shaped like a T. ``letter`` is 'T', and the ``rank`` is a triple, whose entries specify the number of vertices along each path from the branch point (counting the branch point).
* Grassmannian: This defines the cluster algebra (without coefficients) corresponding to the cluster algebra with coefficients which is the co-ordinate ring of a Grassmannian. ``letter`` is 'GR'. ``rank`` is a pair of integers (`k`, `n`) with 'k' < 'n' specifying the Grassmannian of `k`-planes in `n`-space. This defines a quiver given by a (k-1) x (n-k-1) grid where each square is cyclically oriented.
* Exceptional mutation finite quivers: The two exceptional mutation finite quivers, found by Derksen-Owen, have ``letter`` as 'X' and ``rank`` 6 or 7, equal to the number of vertices.
* AE, BE, CE, DE: Quivers are built of one end which looks like type (affine A), B, C, or D, and the other end which looks like type E (i.e., it consists of two antennae, one of length one, and one of length two). ``letter`` is 'AE', 'BE', 'CE', or 'DE', and ``rank`` is the total number of vertices. Note that 'AE' is of a slightly different form and requires ``rank`` to be a pair of integers (i,j) just as in the case of affine type A. See Exercise 4.3 in Kac's book Infinite Dimensional Lie Algebras for more details.
* Infinite type E: It is also possible to obtain infinite-type E quivers by specifying ``letter`` as 'E' and ``rank`` as the number of vertices.
REFERENCES:
- A good reference for finite and affine Dynkin diagrams, including Kac's notation, is the :wikipedia:`Dynkin_diagram`.
- A good reference for the skew-symmetrizable elliptic diagrams is "Cluster algebras of finite mutation type via unfolding" by A. Felikson, M. Shapiro, and P. Tumarkin, [FST2012]_.
EXAMPLES:
Finite types::
sage: QuiverMutationType('A',1) ['A', 1] sage: QuiverMutationType('A',5) ['A', 5]
sage: QuiverMutationType('B',2) ['B', 2] sage: QuiverMutationType('B',5) ['B', 5]
sage: QuiverMutationType('C',2) ['B', 2] sage: QuiverMutationType('C',5) ['C', 5]
sage: QuiverMutationType('D',2) [ ['A', 1], ['A', 1] ] sage: QuiverMutationType('D',3) ['A', 3] sage: QuiverMutationType('D',4) ['D', 4]
sage: QuiverMutationType('E',6) ['E', 6]
sage: QuiverMutationType('G',2) ['G', 2]
sage: QuiverMutationType('A',(1,0),1) ['A', 1]
sage: QuiverMutationType('A',(2,0),1) [ ['A', 1], ['A', 1] ]
sage: QuiverMutationType('A',(7,0),1) ['D', 7]
Affine types::
sage: QuiverMutationType('A',(1,1),1) ['A', [1, 1], 1] sage: QuiverMutationType('A',(2,4),1) ['A', [2, 4], 1]
sage: QuiverMutationType('BB',2,1) ['BB', 2, 1] sage: QuiverMutationType('BB',4,1) ['BB', 4, 1]
sage: QuiverMutationType('CC',2,1) ['CC', 2, 1] sage: QuiverMutationType('CC',4,1) ['CC', 4, 1]
sage: QuiverMutationType('BC',1,1) ['BC', 1, 1] sage: QuiverMutationType('BC',5,1) ['BC', 5, 1]
sage: QuiverMutationType('BD',3,1) ['BD', 3, 1] sage: QuiverMutationType('BD',5,1) ['BD', 5, 1]
sage: QuiverMutationType('CD',3,1) ['CD', 3, 1] sage: QuiverMutationType('CD',5,1) ['CD', 5, 1]
sage: QuiverMutationType('D',4,1) ['D', 4, 1] sage: QuiverMutationType('D',6,1) ['D', 6, 1]
sage: QuiverMutationType('E',6,1) ['E', 6, 1] sage: QuiverMutationType('E',7,1) ['E', 7, 1] sage: QuiverMutationType('E',8,1) ['E', 8, 1]
sage: QuiverMutationType('F',4,1) ['F', 4, 1] sage: QuiverMutationType('F',4,-1) ['F', 4, -1]
sage: QuiverMutationType('G',2,1) ['G', 2, 1] sage: QuiverMutationType('G',2,-1) ['G', 2, -1] sage: QuiverMutationType('A',3,2) == QuiverMutationType('D',3,2) True
Affine types using Kac's Notation::
sage: QuiverMutationType('A',1,1) ['A', [1, 1], 1] sage: QuiverMutationType('B',5,1) ['BD', 5, 1] sage: QuiverMutationType('C',5,1) ['CC', 5, 1] sage: QuiverMutationType('A',2,2) ['BC', 1, 1] sage: QuiverMutationType('A',7,2) ['CD', 4, 1] sage: QuiverMutationType('A',8,2) ['BC', 4, 1] sage: QuiverMutationType('D',6,2) ['BB', 5, 1] sage: QuiverMutationType('E',6,2) ['F', 4, -1] sage: QuiverMutationType('D',4,3) ['G', 2, -1]
Elliptic types::
sage: QuiverMutationType('E',6,[1,1]) ['E', 6, [1, 1]] sage: QuiverMutationType('F',4,[2,1]) ['F', 4, [1, 2]] sage: QuiverMutationType('G',2,[3,3]) ['G', 2, [3, 3]]
Mutation finite types:
rank 2 cases::
sage: QuiverMutationType('R2',(1,1)) ['A', 2] sage: QuiverMutationType('R2',(1,2)) ['B', 2] sage: QuiverMutationType('R2',(1,3)) ['G', 2] sage: QuiverMutationType('R2',(1,4)) ['BC', 1, 1] sage: QuiverMutationType('R2',(1,5)) ['R2', [1, 5]] sage: QuiverMutationType('R2',(2,2)) ['A', [1, 1], 1] sage: QuiverMutationType('R2',(3,5)) ['R2', [3, 5]]
Exceptional Derksen-Owen quivers::
sage: QuiverMutationType('X',6) ['X', 6]
(Mainly) mutation infinite types:
Infinite type E::
sage: QuiverMutationType('E',9) ['E', 8, 1] sage: QuiverMutationType('E',10) ['E', 10] sage: QuiverMutationType('E',12) ['E', 12]
sage: QuiverMutationType('AE',(2,3)) ['AE', [2, 3]] sage: QuiverMutationType('BE',5) ['BE', 5] sage: QuiverMutationType('CE',5) ['CE', 5] sage: QuiverMutationType('DE',6) ['DE', 6]
Grassmannian types::
sage: QuiverMutationType('GR',(2,4)) ['A', 1] sage: QuiverMutationType('GR',(2,6)) ['A', 3] sage: QuiverMutationType('GR',(3,6)) ['D', 4] sage: QuiverMutationType('GR',(3,7)) ['E', 6] sage: QuiverMutationType('GR',(3,8)) ['E', 8] sage: QuiverMutationType('GR',(3,10)) ['GR', [3, 10]]
Triangular types::
sage: QuiverMutationType('TR',2) ['A', 3] sage: QuiverMutationType('TR',3) ['D', 6] sage: QuiverMutationType('TR',4) ['E', 8, [1, 1]] sage: QuiverMutationType('TR',5) ['TR', 5]
T types::
sage: QuiverMutationType('T',(1,1,1)) ['A', 1] sage: QuiverMutationType('T',(1,1,4)) ['A', 4] sage: QuiverMutationType('T',(1,4,4)) ['A', 7] sage: QuiverMutationType('T',(2,2,2)) ['D', 4] sage: QuiverMutationType('T',(2,2,4)) ['D', 6] sage: QuiverMutationType('T',(2,3,3)) ['E', 6] sage: QuiverMutationType('T',(2,3,4)) ['E', 7] sage: QuiverMutationType('T',(2,3,5)) ['E', 8] sage: QuiverMutationType('T',(2,3,6)) ['E', 8, 1] sage: QuiverMutationType('T',(2,3,7)) ['E', 10] sage: QuiverMutationType('T',(3,3,3)) ['E', 6, 1] sage: QuiverMutationType('T',(3,3,4)) ['T', [3, 3, 4]]
Reducible types::
sage: QuiverMutationType(['A',3],['B',4]) [ ['A', 3], ['B', 4] ] """
""" EXAMPLES::
sage: mut_type1 = QuiverMutationType('A',5) sage: mut_type2 = QuiverMutationType('A',5) sage: mut_type3 = QuiverMutationType('A',6) sage: mut_type1 == mut_type2 True sage: mut_type1 == mut_type3 False """
""" Return the string representation of ``self``.
EXAMPLES::
sage: QuiverMutationType(['A',2]) # indirect doctest ['A', 2] """
""" Return the plot of the underlying graph or digraph of ``self``.
INPUT:
- ``circular`` -- (default:``False``) if ``True``, the circular plot is chosen, otherwise >>spring<< is used.
- ``directed`` -- (default: ``True``) if ``True``, the directed version is shown, otherwise the undirected.
EXAMPLES::
sage: QMT = QuiverMutationType(['A',5]) sage: pl = QMT.plot() sage: pl = QMT.plot(circular=True) """
""" Show the plot of the underlying digraph of ``self``.
INPUT:
- ``circular`` -- (default:``False``) if ``True``, the circular plot is chosen, otherwise >>spring<< is used.
- ``directed`` -- (default: ``True``) if ``True``, the directed version is shown, otherwise the undirected.
TESTS::
sage: QMT = QuiverMutationType(['A',5]) sage: QMT.show() # long time """ self.plot( circular=circular, directed=directed ).show()
""" Return the classification letter of ``self``.
EXAMPLES::
sage: mut_type = QuiverMutationType( ['A',5] ); mut_type ['A', 5] sage: mut_type.letter() 'A'
sage: mut_type = QuiverMutationType( ['BC',5,1] ); mut_type ['BC', 5, 1] sage: mut_type.letter() 'BC'
sage: mut_type = QuiverMutationType(['A',3],['B',3]); mut_type [ ['A', 3], ['B', 3] ] sage: mut_type.letter() 'A x B'
sage: mut_type = QuiverMutationType(['A',3],['B',3],['X',6]); mut_type [ ['A', 3], ['B', 3], ['X', 6] ] sage: mut_type.letter() 'A x B x X' """
""" Return the rank in the standard quiver of ``self``.
The rank is the number of vertices.
EXAMPLES::
sage: mut_type = QuiverMutationType( ['A',5] ); mut_type ['A', 5] sage: mut_type.rank() 5
sage: mut_type = QuiverMutationType( ['A',[4,5],1] ); mut_type ['A', [4, 5], 1] sage: mut_type.rank() 9
sage: mut_type = QuiverMutationType( ['BC',5,1] ); mut_type ['BC', 5, 1] sage: mut_type.rank() 6
sage: mut_type = QuiverMutationType(['A',3],['B',3]); mut_type [ ['A', 3], ['B', 3] ] sage: mut_type.rank() 6
sage: mut_type = QuiverMutationType(['A',3],['B',3],['X',6]); mut_type [ ['A', 3], ['B', 3], ['X', 6] ] sage: mut_type.rank() 12 """
def b_matrix(self): """ Return the B-matrix of the standard quiver of ``self``.
The conventions for B-matrices agree with Fomin-Zelevinsky (up to a reordering of the simple roots).
EXAMPLES::
sage: mut_type = QuiverMutationType( ['A',5] ); mut_type ['A', 5] sage: mut_type.b_matrix() [ 0 1 0 0 0] [-1 0 -1 0 0] [ 0 1 0 1 0] [ 0 0 -1 0 -1] [ 0 0 0 1 0]
sage: mut_type = QuiverMutationType(['A',3],['B',3]); mut_type [ ['A', 3], ['B', 3] ] sage: mut_type.b_matrix() [ 0 1 0 0 0 0] [-1 0 -1 0 0 0] [ 0 1 0 0 0 0] [ 0 0 0 0 1 0] [ 0 0 0 -1 0 -1] [ 0 0 0 0 2 0] """
def standard_quiver(self): """ Return the standard quiver of ``self``.
EXAMPLES::
sage: mut_type = QuiverMutationType( ['A',5] ); mut_type ['A', 5] sage: mut_type.standard_quiver() Quiver on 5 vertices of type ['A', 5]
sage: mut_type = QuiverMutationType( ['A',[5,3],1] ); mut_type ['A', [3, 5], 1] sage: mut_type.standard_quiver() Quiver on 8 vertices of type ['A', [3, 5], 1]
sage: mut_type = QuiverMutationType(['A',3],['B',3]); mut_type [ ['A', 3], ['B', 3] ] sage: mut_type.standard_quiver() Quiver on 6 vertices of type [ ['A', 3], ['B', 3] ]
sage: mut_type = QuiverMutationType(['A',3],['B',3],['X',6]); mut_type [ ['A', 3], ['B', 3], ['X', 6] ] sage: mut_type.standard_quiver() Quiver on 12 vertices of type [ ['A', 3], ['B', 3], ['X', 6] ] """
def cartan_matrix(self): """ Return the Cartan matrix of ``self``.
Note that (up to a reordering of the simple roots) the convention for the definition of Cartan matrix, used here and elsewhere in Sage, agrees with the conventions of Kac, Fulton-Harris, and Fomin-Zelevinsky, but disagrees with the convention of Bourbaki. The `(i,j)` entry is `2(\\alpha_i,\\alpha_j)/(\\alpha_i,\\alpha_i)`.
EXAMPLES::
sage: mut_type = QuiverMutationType(['A',5]); mut_type ['A', 5] sage: mut_type.cartan_matrix() [ 2 -1 0 0 0] [-1 2 -1 0 0] [ 0 -1 2 -1 0] [ 0 0 -1 2 -1] [ 0 0 0 -1 2]
sage: mut_type = QuiverMutationType(['A',3],['B',3]); mut_type [ ['A', 3], ['B', 3] ] sage: mut_type.cartan_matrix() [ 2 -1 0 0 0 0] [-1 2 -1 0 0 0] [ 0 -1 2 0 0 0] [ 0 0 0 2 -1 0] [ 0 0 0 -1 2 -1] [ 0 0 0 0 -2 2] """ # as soon as CartanMatrix is implemented we should use it here: # from sage.combinat.root_system.cartan_matrix import CartanMatrix # return CartanMatrix(cmat)
""" Return ``True`` if ``self`` is irreducible.
EXAMPLES::
sage: mt = QuiverMutationType(['A',2]) sage: mt.is_irreducible() True """
""" Return ``True`` if ``self`` is of finite mutation type.
This means that its mutation class has only finitely many different B-matrices.
EXAMPLES::
sage: mt = QuiverMutationType(['D',5,1]) sage: mt.is_mutation_finite() True """
""" Return ``True`` if ``self`` is simply laced.
This means that the only arrows that appear in the quiver of ``self`` are single unlabelled arrows.
EXAMPLES::
sage: mt = QuiverMutationType(['A',2]) sage: mt.is_simply_laced() True
sage: mt = QuiverMutationType(['B',2]) sage: mt.is_simply_laced() False
sage: mt = QuiverMutationType(['A',(1,1),1]) sage: mt.is_simply_laced() False """
""" Return ``True`` if the B-matrix of ``self`` is skew-symmetric.
EXAMPLES::
sage: mt = QuiverMutationType(['A',2]) sage: mt.is_skew_symmetric() True
sage: mt = QuiverMutationType(['B',2]) sage: mt.is_skew_symmetric() False
sage: mt = QuiverMutationType(['A',(1,1),1]) sage: mt.is_skew_symmetric() True """
""" Return ``True`` if ``self`` is of finite type.
This means that the cluster algebra associated to ``self`` has only a finite number of cluster variables.
EXAMPLES::
sage: mt = QuiverMutationType(['A',2]) sage: mt.is_finite() True
sage: mt = QuiverMutationType(['A',[4,2],1]) sage: mt.is_finite() False """
""" Return ``True`` if ``self`` is of affine type.
EXAMPLES::
sage: mt = QuiverMutationType(['A',2]) sage: mt.is_affine() False
sage: mt = QuiverMutationType(['A',[4,2],1]) sage: mt.is_affine() True """ else:
""" Return ``True`` if ``self`` is of elliptic type.
EXAMPLES::
sage: mt = QuiverMutationType(['A',2]) sage: mt.is_elliptic() False
sage: mt = QuiverMutationType(['E',6,[1,1]]) sage: mt.is_elliptic() True """ else:
""" Print a scheme of all properties of ``self``.
Most properties have natural definitions for either irreducible or reducible types. ``affine`` and ``elliptic`` are only defined for irreducible types.
EXAMPLES::
sage: mut_type = QuiverMutationType(['A',3]); mut_type ['A', 3] sage: mut_type.properties() ['A', 3] has rank 3 and the following properties: - irreducible: True - mutation finite: True - simply-laced: True - skew-symmetric: True - finite: True - affine: False - elliptic: False
sage: mut_type = QuiverMutationType(['B',3]); mut_type ['B', 3] sage: mut_type.properties() ['B', 3] has rank 3 and the following properties: - irreducible: True - mutation finite: True - simply-laced: False - skew-symmetric: False - finite: True - affine: False - elliptic: False
sage: mut_type = QuiverMutationType(['B',3,1]); mut_type ['BD', 3, 1] sage: mut_type.properties() ['BD', 3, 1] has rank 4 and the following properties: - irreducible: True - mutation finite: True - simply-laced: False - skew-symmetric: False - finite: False - affine: True - elliptic: False
sage: mut_type = QuiverMutationType(['E',6,[1,1]]); mut_type ['E', 6, [1, 1]] sage: mut_type.properties() ['E', 6, [1, 1]] has rank 8 and the following properties: - irreducible: True - mutation finite: True - simply-laced: False - skew-symmetric: True - finite: False - affine: False - elliptic: True
sage: mut_type = QuiverMutationType(['A',3],['B',3]); mut_type [ ['A', 3], ['B', 3] ] sage: mut_type.properties() [ ['A', 3], ['B', 3] ] has rank 6 and the following properties: - irreducible: False - mutation finite: True - simply-laced: False - skew-symmetric: False - finite: True
sage: mut_type = QuiverMutationType('GR',[4,9]); mut_type ['GR', [4, 9]] sage: mut_type.properties() ['GR', [4, 9]] has rank 12 and the following properties: - irreducible: True - mutation finite: False - simply-laced: True - skew-symmetric: True - finite: False - affine: False - elliptic: False """
""" The mutation type for a cluster algebra or a quiver. Should not be called directly, but through QuiverMutationType. """ """ Should not be called directly but through QuiverMutationType.
INPUT:
- ``letter`` -- the letter of the mutation type - ``rank`` -- the rank of the mutation type - ``twist`` -- the twist of the mutation type
EXAMPLES::
sage: QuiverMutationType('A',5) ['A', 5]
sage: QuiverMutationType('A',[4,5],1) ['A', [4, 5], 1]
sage: QuiverMutationType('BB',5,1) ['BB', 5, 1]
sage: QuiverMutationType('X',6) ['X', 6] """ # _rank and _bi_rank are initialized
# _graph and _digraph are initialized
# _info is initialized
# _letter/twist is the input letter/twist
# type A (finite and affine) rank = list( rank ) data[1] = rank else: _mutation_type_error( data ) # types ['A',1] and ['A',[0,1],1] need to be treated on # itself (as there is no edge) # type ['A',[1,1],1] needs to be treated on itself as well # (as there is a double edge) else: else:
# type B (finite) else: _mutation_type_error( data ) else:
# type C (finite) else: _mutation_type_error( data ) else:
# type BB (affine) else: _mutation_type_error( data ) else:
# type CC (affine) else: _mutation_type_error( data ) else:
# type BC (affine) else: _mutation_type_error( data ) else: else:
# type BD (affine) else: _mutation_type_error( data ) else:
# type CD (affine) else: _mutation_type_error( data ) else:
# type D (finite and affine) else: _mutation_type_error( data )
# type E (finite, affine and elliptic) (3, 4), (4, 5), (2, 6)]) (3, 4), (4, 5), (5, 6),(2, 7)]) # type E (mutation infinite) else: _mutation_type_error(data)
# type AE (mutation infinite) rank = list( rank ) data[1] = rank self._graph.add_edges( [(0,1,2),(1,2,None)] ) else: else: else: _mutation_type_error( data )
# type BE (mutation infinite) self._graph.add_edge( rank-3,rank-2,(2,-1) ) else: else: _mutation_type_error( data )
# type CE (mutation infinite) self._graph.add_edge( rank-3,rank-2,(1,-2) ) else: else: _mutation_type_error( data )
# type DE (mutation infinite) else: _mutation_type_error( data )
# type F (finite, affine, and elliptic) (2,3,(1,-2)),(3,4,None) ] ) (2,3,(2,-1)),(3,4,None) ] ) (2,3,(2,-1)), (4,2,(1,-2)), (3,4,2), (4,5,None), (5,3,None) ]) (2,3,(1,-2)), (4,2,(2,-1)), (3,4,2), (4,5,None), (5,3,None) ]) elif rank == 4 and twist == [2,2]: self._rank = rank + 2 self._info['mutation_finite'] = True self._info['elliptic'] = True self._digraph.add_edges( [ (0,1,None), (1,2,None), (3,1,None), (2,3,2), (4,2,(2,-1)), (3,4,(1,-2)), (5,4,None) ] ) elif rank == 4 and twist == [1,1]: self._rank = rank + 2 self._info['mutation_finite'] = True self._info['elliptic'] = True self._digraph.add_edges( [ (0,1,None), (1,2,None), (3,1,None), (2,3,2), (4,2,(1,-2)), (3,4,(2,-1)), (5,4,None) ] ) else: _mutation_type_error( data )
# type G (finite, affine, and elliptic) (3,1,(1,-3)), (2,3,2)] ) (3,1,(3,-1)), (2,3,2)] ) (2,1,None), (2,3, (1,-3))]) elif rank == 2 and twist == [1,1]: self._rank = rank + 2 self._info['mutation_finite'] = True self._info['elliptic'] = True self._digraph.add_edges( [ (1,0,None), (0,2,2), (3,0,(1,-3)), (2,1,None), (2,3,(3,-1)) ] ) else: _mutation_type_error( data )
# type GR (mutation infinite) else: else: else: _mutation_type_error( data )
# type R2 (rank 2 finite mutation types) else: _mutation_type_error( data )
# type T rank = list( rank ) data[1] = rank else: else: _mutation_type_error( data )
# type TR (mutation infinite if rank > 2) # type ['TR',1] needs to be treated on itself (as there is no edge) self._graph.add_vertex( 0 ) else: _mutation_type_error( data )
# type X (2,3,None),(3,4,2),(4,2,None), (2,5,None) ] ) self._digraph.add_edges( [ (5,6,2),(6,2,None) ] ) else: _mutation_type_error( data )
# otherwise, an error is raised else:
# in the bipartite case, the digraph is constructed from the graph else: raise ValueError('The QuiverMutationType does not have ' 'a Coxeter diagram.')
# in the other cases, the graph is constructed from the digraph
# _description is as for CartanType
""" Return a list of all irreducible components of ``self``.
EXAMPLES::
sage: mut_type = QuiverMutationType('A',3); mut_type ['A', 3] sage: mut_type.irreducible_components() (['A', 3],) """
def class_size(self): """ If it is known, the size of the mutation class of all quivers which are mutation equivalent to the standard quiver of ``self`` (up to isomorphism) is returned.
Otherwise, ``NotImplemented`` is returned.
Formula for finite type A is taken from Torkildsen - Counting cluster-tilted algebras of type `A_n`. Formulas for affine type A and finite type D are taken from Bastian, Prellberg, Rubey, Stump - Counting the number of elements in the mutation classes of `\widetilde A_n` quivers. Formulas for finite and affine types B and C are proven but not yet published. Conjectural formulas for several other non-simply-laced affine types are implemented. Exceptional Types (finite, affine, and elliptic) E, F, G, and X are hardcoded.
EXAMPLES::
sage: mut_type = QuiverMutationType( ['A',5] ); mut_type ['A', 5] sage: mut_type.class_size() 19
sage: mut_type = QuiverMutationType( ['A',[10,3],1] ); mut_type ['A', [3, 10], 1] sage: mut_type.class_size() 142120
sage: mut_type = QuiverMutationType( ['B',6] ); mut_type ['B', 6] sage: mut_type.class_size() 132
sage: mut_type = QuiverMutationType( ['BD',6,1] ); mut_type ['BD', 6, 1] sage: mut_type.class_size() Warning: This method uses a formula which has not been proved correct. 504
Check that :trac:`14048` is fixed::
sage: mut_type = QuiverMutationType( ['F',4,(2,1)] ) sage: mut_type.class_size() 90 """ return infinity
# type A (finite and affine) # the formula is taken from Torkildsen - Counting # cluster-tilted algebras of type A # the formula is taken from Bastian, Prellberg, Rubey, Stump return ( binomial( 2*i,i ) + sum( f(k) * binomial(2*i//k,i//k)**2 for k in [k for k in i.divisors() if k in j.divisors()] ) // n ) // 4 else: binomial(2*j//k,j//k) for k in [k for k in i.divisors() if k in j.divisors()] ) // ( 2 * n )
# types B and C (finite and affine) # this formula is proven but nowhere published correctness # is clear enough that I don't think a warning is needed
# these two formulas are not yet proven print(Warning("Warning: This method uses a formula " "which has not been proved correct.")) if self.is_affine(): if self._twist == 1: n = self._rank - 1 if n%2==1: return binomial( 2*n-1, n-1 ) else: return binomial( 2*n-1, n-1 ) + binomial( n-1, n//2 -1 )
# type BC (affine) # this formula is not yet proven print(Warning("Warning: This method uses a formula " "which has not been proved correct.")) if self.is_affine(): if self._twist == 1: n = self._rank - 1 return binomial( 2*n, n )
# types BD and CD (affine) # this formula is not yet proven "which has not been proved correct."))
# type D (finite and affine) # the formula is taken from Bastian, Prellberg, Rubey, Stump if self.is_finite(): if self._rank == 4: return 6 else: f = Euler_Phi() n = ZZ(self._rank) return sum( f( n//k ) * binomial( 2*k, k ) for k in n.divisors() ) // (2*n) # this formula is not yet proven elif self.is_affine(): n = self._rank - 3 if n == 2: return 9 else: print(Warning ("Warning: This method uses a formula " "which has not been proved correct.")) if n%2==1: return 2*binomial(2*n,n) else: return 2*binomial(2*n,n) + binomial(n, n//2)
# the exceptional types are hard-coded # type E (finite, affine and elliptic) if self.is_finite(): if self._rank == 6: return 67 elif self._rank == 7: return 416 elif self._rank == 8: return 1574 elif self.is_affine(): if self._rank == 7: return 132 elif self._rank == 8: return 1080 elif self._rank == 9: return 7560 elif self.is_elliptic(): if self._rank == 8: return 49 elif self._rank == 9: return 506 elif self._rank == 10: return 5739
# type F return 15 return 60 if self._twist == [1,1] or self._twist == [2,2]: return 35
# type G if self.is_finite(): return 2 elif self.is_affine(): return 6 elif self.is_elliptic(): if self._twist == [1,3]: return 7 if self._twist == [1,1] or self._twist == [3,3]: return 2
# type X elif self._rank == 7: return 2
# otherwise the size is returned to be unknown else: print("Size unknown") return NotImplemented
""" Return the QuiverMutationType which is dual to ``self``.
EXAMPLES::
sage: mut_type = QuiverMutationType('A',5); mut_type ['A', 5] sage: mut_type.dual() ['A', 5]
sage: mut_type = QuiverMutationType('B',5); mut_type ['B', 5] sage: mut_type.dual() ['C', 5] sage: mut_type.dual().dual() ['B', 5] sage: mut_type.dual().dual() == mut_type True """ # the self-dual cases rank -= 1 # the cases F and G have non-trivial duality in some cases if self.is_finite(): return self elif self.is_affine(): rank = self._rank - 1 twist = - self._twist elif self.is_elliptic(): twist = self._twist rank = self._rank - 2 if letter == 'F': if self._twist == [2,2]: twist == [1,1] if self._twist == [1,1]: twist == [2,2] if letter == 'G': if self._twist == [3,3]: twist = [1,1] elif self._twist == [1,1]: twist = [3,3] else: rank = self._rank return QuiverMutationType(letter,rank,twist) else:
""" The mutation type for a cluster algebra or a quiver. Should not be called directly, but through QuiverMutationType. Inherits from QuiverMutationType_abstract. """ """ Should not be called directly, but through QuiverMutationType.
INPUT:
- ``data`` -- a list each of whose entries is a QuiverMutationType_Irreducible
EXAMPLES::
sage: QuiverMutationType(['A',4],['B',6]) [ ['A', 4], ['B', 6] ] """ return _mutation_type_error(data)
# _info is initialized for comp in data) for comp in data) for comp in data)
# letter and rank are initialized
# graph and digraph are initialized
labels='integers') labels='integers')
# _description is as for CartanType
""" Return a list of all irreducible components of ``self``.
EXAMPLES::
sage: mut_type = QuiverMutationType('A',3); mut_type ['A', 3] sage: mut_type.irreducible_components() (['A', 3],)
sage: mut_type = QuiverMutationType(['A',3],['B',3]); mut_type [ ['A', 3], ['B', 3] ] sage: mut_type.irreducible_components() (['A', 3], ['B', 3])
sage: mut_type = QuiverMutationType(['A',3],['B',3],['X',6]) sage: mut_type [ ['A', 3], ['B', 3], ['X', 6] ] sage: mut_type.irreducible_components() (['A', 3], ['B', 3], ['X', 6]) """
def class_size(self): """ If it is known, the size of the mutation class of all quivers which are mutation equivalent to the standard quiver of ``self`` (up to isomorphism) is returned.
Otherwise, ``NotImplemented`` is returned.
EXAMPLES::
sage: mut_type = QuiverMutationType(['A',3],['B',3]); mut_type [ ['A', 3], ['B', 3] ] sage: mut_type.class_size() 20
sage: mut_type = QuiverMutationType(['A',3],['B',3],['X',6]) sage: mut_type [ ['A', 3], ['B', 3], ['X', 6] ] sage: mut_type.class_size() 100 """ return infinity else: else: y = components.index(x) multiplicities[y] = multiplicities[y]+1
print("Size unknown") return NotImplemented else: multiplicities[i] ) for i in range (0,len(sizes))])
""" Return the QuiverMutationType which is dual to ``self``.
EXAMPLES::
sage: mut_type = QuiverMutationType(['A',5],['B',6],['C',5],['D',4]); mut_type [ ['A', 5], ['B', 6], ['C', 5], ['D', 4] ] sage: mut_type.dual() [ ['A', 5], ['C', 6], ['B', 5], ['D', 4] ] """
r""" Return a dict with keys being tuples representing regular QuiverMutationTypes of the given rank, and with values being lists or sets containing all mutation equivalent quivers as dig6 data.
EXAMPLES::
sage: from sage.combinat.cluster_algebra_quiver.quiver_mutation_type import _construct_classical_mutation_classes sage: rank_2_classes = _construct_classical_mutation_classes(2) # long time sage: for mut_class in sorted(rank_2_classes.keys(),key=str): # long time ....: print("{} {}".format(mut_class, rank_2_classes[mut_class])) ('A', (1, 1), 1) [('AO', (((0, 1), (2, -2)),))] ('A', 2) [('AO', ())] ('B', 2) [('AO', (((0, 1), (1, -2)),)), ('AO', (((0, 1), (2, -1)),))] ('BC', 1, 1) [('AO', (((0, 1), (1, -4)),)), ('AO', (((0, 1), (4, -1)),))] """
# finite A # affine A # finite B # affine B data[ ('BB',n-1,1) ] = ClusterQuiver(['BB',n-1,1]).mutation_class(data_type='dig6') # finite C data[ ('C',n) ] = ClusterQuiver(['C',n]).mutation_class(data_type='dig6') # affine C # affine CC data[ ('CC',n-1,1) ] = ClusterQuiver(['CC',n-1,1]).mutation_class(data_type='dig6') # affine BD data[ ('BD',n-1,1) ] = ClusterQuiver(['BD',n-1,1]).mutation_class(data_type='dig6') # affine CD data[ ('CD',n-1,1) ] = ClusterQuiver(['CD',n-1,1]).mutation_class(data_type='dig6') # finite D data[ ('D',n) ] = ClusterQuiver(['D',n]).mutation_class(data_type='dig6') # affine D data[ ('D',n-1,1) ] = ClusterQuiver(['D',n-1,1]).mutation_class(data_type='dig6')
r""" Return a dict with keys being tuples representing exceptional QuiverMutationTypes of the given rank, and with values being lists or sets containing all mutation equivalent quivers as dig6 data.
EXAMPLES::
sage: from sage.combinat.cluster_algebra_quiver.quiver_mutation_type import _construct_exceptional_mutation_classes sage: rank_3_exceptional = _construct_exceptional_mutation_classes(3) # long time sage: for mut_class in sorted(rank_3_exceptional.keys(), key=str): # long time ....: print("{} {}".format(mut_class, rank_3_exceptional[mut_class])) ('G', 2, -1) [('BH?', (((1, 2), (1, -3)),)), ('BGO', (((2, 1), (3, -1)),)), ('BW?', (((0, 1), (3, -1)),)), ('BP?', (((0, 1), (1, -3)),)), ('BP_', (((0, 1), (1, -3)), ((2, 0), (3, -1)))), ('BP_', (((0, 1), (3, -1)), ((1, 2), (1, -3)), ((2, 0), (2, -2))))] ('G', 2, 1) [('BH?', (((1, 2), (3, -1)),)), ('BGO', (((2, 1), (1, -3)),)), ('BW?', (((0, 1), (1, -3)),)), ('BP?', (((0, 1), (3, -1)),)), ('BKO', (((1, 0), (3, -1)), ((2, 1), (1, -3)))), ('BP_', (((0, 1), (2, -2)), ((1, 2), (1, -3)), ((2, 0), (3, -1))))] """ # finite E data[ ('E',n) ] = ClusterQuiver(['E',n]).mutation_class(data_type='dig6') # affine E data[ ('E',n-1,1) ] = ClusterQuiver(['E',n-1,1]).mutation_class(data_type='dig6') # elliptic E data[ ('E',n-2,(1,1)) ] = ClusterQuiver(['E',n-2,[1,1]]).mutation_class(data_type='dig6') # finite F data[ ('F',4) ] = ClusterQuiver(['F',4]).mutation_class(data_type='dig6') # affine F data[ ('F',4,1) ] = ClusterQuiver(['F',4,1]).mutation_class(data_type='dig6') data[ ('F',4,-1) ] = ClusterQuiver(['F',4,-1]).mutation_class(data_type='dig6') # finite G # affine G data[ ('G',2,1) ] = ClusterQuiver(['G',2,1]).mutation_class(data_type='dig6') data[ ('G',2,-1) ] = ClusterQuiver(['G',2,-1]).mutation_class(data_type='dig6') # elliptic G data[ ('G',2,(1,3)) ] = ClusterQuiver(['G',2,(1,3)]).mutation_class(data_type='dig6') data[ ('G',2,(1,1)) ] = ClusterQuiver(['G',2,(1,1)]).mutation_class(data_type='dig6') data[ ('G',2,(3,3)) ] = ClusterQuiver(['G',2,(3,3)]).mutation_class(data_type='dig6') # X data[ ('X',n) ] = ClusterQuiver(['X',n]).mutation_class(data_type='dig6') # elliptic F data[ ('F',4,(1,2)) ] = ClusterQuiver(['F',4,(1,2)]).mutation_class(data_type='dig6') data[ ('F',4,(1,1)) ] = ClusterQuiver(['F',4,(1,1)]).mutation_class(data_type='dig6') data[ ('F',4,(2,2)) ] = ClusterQuiver(['F',4,(2,2)]).mutation_class(data_type='dig6')
""" Save all exceptional mutation classes as dig6 data into the file ``exc_classes_n.dig6`` in the folder ``DOT_SAGE``.
TESTS::
sage: from sage.combinat.cluster_algebra_quiver.quiver_mutation_type import save_quiver_data sage: save_quiver_data(2) # indirect doctest <BLANKLINE> The following types are saved to file ... and will now be used to determine quiver mutation types: [('A', 1)] <BLANKLINE> The following types are saved to file ... and will now be used to determine quiver mutation types: [('A', (1, 1), 1), ('A', 2), ('B', 2), ('BC', 1, 1), ('G', 2)]
sage: save_quiver_data(2,up_to=False) # indirect doctest <BLANKLINE> The following types are saved to file ... and will now be used to determine quiver mutation types: [('A', (1, 1), 1), ('A', 2), ('B', 2), ('BC', 1, 1), ('G', 2)]
sage: save_quiver_data(2,up_to=False, types='Classical') # indirect doctest <BLANKLINE> The following types are saved to file ... and will now be used to determine quiver mutation types: [('A', (1, 1), 1), ('A', 2), ('B', 2), ('BC', 1, 1)]
sage: save_quiver_data(2,up_to=False, types='Exceptional') # indirect doctest <BLANKLINE> The following types are saved to file ... and will now be used to determine quiver mutation types: [('G', 2)]
sage: save_quiver_data(2,up_to=False, verbose=False) # indirect doctest """ raise ValueError('The third input must be either ClassicalExceptional' ' (default), Classical, or Exceptional.')
r""" Save mutation classes of certain quivers of ranks up to and equal to ``n`` or equal to ``n`` to ``DOT_SAGE/cluster_algebra_quiver/mutation_classes_n.dig6``.
This data will then be used to determine quiver mutation types.
INPUT:
- ``n``: the rank (or the upper limit on the rank) of the mutation classes that are being saved.
- ``up_to`` -- (default:``True``) if ``True``, saves data for ranks smaller than or equal to ``n``. If ``False``, saves data for rank exactly ``n``.
- ``types`` -- (default:'ClassicalExceptional') if all, saves data for both exceptional mutation-finite quivers and for classical quiver. The input 'Exceptional' or 'Classical' is also allowed to save only part of this data.
TESTS::
sage: from sage.combinat.cluster_algebra_quiver.quiver_mutation_type import save_quiver_data sage: save_quiver_data(2) <BLANKLINE> The following types are saved to file ... and will now be used to determine quiver mutation types: [('A', 1)] <BLANKLINE> The following types are saved to file ... and will now be used to determine quiver mutation types: [('A', (1, 1), 1), ('A', 2), ('B', 2), ('BC', 1, 1), ('G', 2)]
sage: save_quiver_data(2,up_to=False) <BLANKLINE> The following types are saved to file ... and will now be used to determine quiver mutation types: [('A', (1, 1), 1), ('A', 2), ('B', 2), ('BC', 1, 1), ('G', 2)]
sage: save_quiver_data(2,up_to=False, types='Classical') <BLANKLINE> The following types are saved to file ... and will now be used to determine quiver mutation types: [('A', (1, 1), 1), ('A', 2), ('B', 2), ('BC', 1, 1)]
sage: save_quiver_data(2,up_to=False, types='Exceptional') <BLANKLINE> The following types are saved to file ... and will now be used to determine quiver mutation types: [('G', 2)]
sage: save_quiver_data(2,up_to=False, verbose=False) """ # we finally clear the load_data
""" Return a digraph obtained from a bipartite graph g by choosing one set of the bipartition to be the set of sinks and the other to be the set of sources.
EXAMPLES::
sage: from sage.combinat.cluster_algebra_quiver.quiver_mutation_type \ import _bipartite_graph_to_digraph sage: G = Graph([(1,2)]) sage: _bipartite_graph_to_digraph(G) Digraph on 2 vertices """ raise ValueError('The input graph is not bipartite.')
else:
""" Return ``True`` if ``data`` is a QuiverMutationType.
EXAMPLES::
sage: from sage.combinat.cluster_algebra_quiver.quiver_mutation_type import _is_mutation_type sage: _is_mutation_type ( [ 'A', 2 ] ) True sage: _is_mutation_type ( [ 'P', 1 ] ) False """
""" Output an error message because data which is not a valid quiver mutation type has been passed to QuiverMutationType.
EXAMPLES::
sage: QuiverMutationType( 'Christian', 'Stump' ) # indirect doctest Traceback (most recent call last): ... ValueError: ['Christian', 'Stump'] is not a valid quiver mutation type Finite types have the form [ '?', n ] for type ? and rank n Affine type A has the form [ 'A', [ i, j ], 1 ] for rank i+j Affine type ? has the form [ '?', k, \pm 1 ] for rank k+1 Elliptic type ? has the form [ '?', k, [i, j] ] (1 <= i,j <= 3) for rank k+2 For correct syntax in other types, please consult the documentation. """
r""" Return the matrix obtained from the edge list of a quiver.
INPUT:
- ``edges`` -- the list of edges - ``nlist`` -- the list of mutable vertices of the quiver - ``mlist`` -- the list of frozen vertices of the quiver
OUTPUT:
An `(n+m) \times n` matrix corresponding to the edge-list.
EXAMPLES::
sage: from sage.combinat.cluster_algebra_quiver.quiver_mutation_type import _edge_list_to_matrix sage: G = QuiverMutationType(['A',2])._digraph sage: _edge_list_to_matrix(G.edges(), [0,1], []) [ 0 1] [-1 0]
sage: G2 = DiGraph([('a', 'b', 1)]) sage: _edge_list_to_matrix(G2.edges(), ['a', 'b'], []) [ 0 1] [-1 0]
sage: G3 = DiGraph([('a', 'b', 1), ('b', 'c', 1)]) sage: _edge_list_to_matrix(G3.edges(), ['a', 'b'], ['c']) [ 0 1] [-1 0] [ 0 -1] """ edge = (edge[0], edge[1], (1, -1))
|