ClusterSeed#

A cluster seed is a pair \((B,\mathbf{x})\) with \(B\) being a skew-symmetrizable \((n+m) \times n\) -matrix and with \(\mathbf{x}\) being an \(n\)-tuple of independent elements in the field of rational functions in \(n\) variables.

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

AUTHORS:

  • Gregg Musiker: Initial Version

  • Christian Stump: Initial Version

  • Aram Dermenjian (2015-07-01): Updating ability to not rely solely on clusters

  • Jesse Levitt (2015-07-01): Updating ability to not rely solely on clusters

REFERENCES:

See also

For mutation types of cluster seeds, see sage.combinat.cluster_algebra_quiver.quiver_mutation_type.QuiverMutationType(). Cluster seeds are closely related to sage.combinat.cluster_algebra_quiver.quiver.ClusterQuiver().

class sage.combinat.cluster_algebra_quiver.cluster_seed.ClusterSeed(data, frozen=None, is_principal=False, user_labels=None, user_labels_prefix='x')[source]#

Bases: SageObject

The cluster seed associated to an exchange matrix.

INPUT:

  • data – can be any of the following:

    * :class:`QuiverMutationType`
    
    • str – a 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

EXAMPLES:

sage: S = ClusterSeed(['A',5]); S
A seed for a cluster algebra of rank 5 of type ['A', 5]

sage: S = ClusterSeed(['A',[2,5],1]); S
A seed for a cluster algebra of rank 7 of type ['A', [2, 5], 1]

sage: T = ClusterSeed(S); T
A seed for a cluster algebra of rank 7 of type ['A', [2, 5], 1]

sage: T = ClusterSeed(S._M); T
A seed for a cluster algebra of rank 7

sage: T = ClusterSeed(S.quiver()._digraph); T
A seed for a cluster algebra of rank 7

sage: T = ClusterSeed(S.quiver()._digraph.edges(sort=True)); T
A seed for a cluster algebra of rank 7

sage: S = ClusterSeed(['B',2]); S
A seed for a cluster algebra of rank 2 of type ['B', 2]

sage: S = ClusterSeed(['C',2]); S
A seed for a cluster algebra of rank 2 of type ['B', 2]

sage: S = ClusterSeed(['A', [5,0],1]); S
A seed for a cluster algebra of rank 5 of type ['D', 5]

sage: S = ClusterSeed(['GR',[3,7]]); S
A seed for a cluster algebra of rank 6 of type ['E', 6]

sage: S = ClusterSeed(['F', 4, [2,1]]); S
A seed for a cluster algebra of rank 6 of type ['F', 4, [1, 2]]

sage: S = ClusterSeed(['A',4]); S._use_fpolys
True
sage: S._use_d_vec
True
sage: S._use_g_vec
True
sage: S._use_c_vec
True

sage: S = ClusterSeed(['A', 4]); S.use_fpolys(False); S._use_fpolys
False

sage: S = ClusterSeed(DiGraph([['a', 'b'], ['c', 'b'], ['c', 'd'], ['e', 'd']]),
....:                 frozen=['c']); S
A seed for a cluster algebra of rank 4 with 1 frozen variable

sage: S = ClusterSeed(['D', 4], user_labels=[-1, 0, 1, 2]); S
A seed for a cluster algebra of rank 4 of type ['D', 4]
>>> from sage.all import *
>>> S = ClusterSeed(['A',Integer(5)]); S
A seed for a cluster algebra of rank 5 of type ['A', 5]

>>> S = ClusterSeed(['A',[Integer(2),Integer(5)],Integer(1)]); S
A seed for a cluster algebra of rank 7 of type ['A', [2, 5], 1]

>>> T = ClusterSeed(S); T
A seed for a cluster algebra of rank 7 of type ['A', [2, 5], 1]

>>> T = ClusterSeed(S._M); T
A seed for a cluster algebra of rank 7

>>> T = ClusterSeed(S.quiver()._digraph); T
A seed for a cluster algebra of rank 7

>>> T = ClusterSeed(S.quiver()._digraph.edges(sort=True)); T
A seed for a cluster algebra of rank 7

>>> S = ClusterSeed(['B',Integer(2)]); S
A seed for a cluster algebra of rank 2 of type ['B', 2]

>>> S = ClusterSeed(['C',Integer(2)]); S
A seed for a cluster algebra of rank 2 of type ['B', 2]

>>> S = ClusterSeed(['A', [Integer(5),Integer(0)],Integer(1)]); S
A seed for a cluster algebra of rank 5 of type ['D', 5]

>>> S = ClusterSeed(['GR',[Integer(3),Integer(7)]]); S
A seed for a cluster algebra of rank 6 of type ['E', 6]

>>> S = ClusterSeed(['F', Integer(4), [Integer(2),Integer(1)]]); S
A seed for a cluster algebra of rank 6 of type ['F', 4, [1, 2]]

>>> S = ClusterSeed(['A',Integer(4)]); S._use_fpolys
True
>>> S._use_d_vec
True
>>> S._use_g_vec
True
>>> S._use_c_vec
True

>>> S = ClusterSeed(['A', Integer(4)]); S.use_fpolys(False); S._use_fpolys
False

>>> S = ClusterSeed(DiGraph([['a', 'b'], ['c', 'b'], ['c', 'd'], ['e', 'd']]),
...                 frozen=['c']); S
A seed for a cluster algebra of rank 4 with 1 frozen variable

>>> S = ClusterSeed(['D', Integer(4)], user_labels=[-Integer(1), Integer(0), Integer(1), Integer(2)]); S
A seed for a cluster algebra of rank 4 of type ['D', 4]
LLM_gen_set(size_limit=-1)[source]#

Produce a list of upper cluster algebra elements corresponding to all vectors in \(\{0,1\}^n\).

INPUT:

  • B – a skew-symmetric matrix.

  • size_limit – a limit on how many vectors you want the function to return.

OUTPUT:

An array of elements in the upper cluster algebra.

EXAMPLES:

sage: B = matrix([[0,1,0],[-1,0,1],[0,-1,0],[1,0,0],[0,1,0],[0,0,1]])
sage: C = ClusterSeed(B)
sage: C.LLM_gen_set()
[1,
 (x1 + x3)/x0,
 (x0*x4 + x2)/x1,
 (x0*x3*x4 + x1*x2 + x2*x3)/(x0*x1),
 (x1*x5 + 1)/x2,
 (x1^2*x5 + x1*x3*x5 + x1 + x3)/(x0*x2),
 (x0*x1*x4*x5 + x0*x4 + x2)/(x1*x2),
 (x0*x1*x3*x4*x5 + x0*x3*x4 + x1*x2 + x2*x3)/(x0*x1*x2)]
>>> from sage.all import *
>>> B = matrix([[Integer(0),Integer(1),Integer(0)],[-Integer(1),Integer(0),Integer(1)],[Integer(0),-Integer(1),Integer(0)],[Integer(1),Integer(0),Integer(0)],[Integer(0),Integer(1),Integer(0)],[Integer(0),Integer(0),Integer(1)]])
>>> C = ClusterSeed(B)
>>> C.LLM_gen_set()
[1,
 (x1 + x3)/x0,
 (x0*x4 + x2)/x1,
 (x0*x3*x4 + x1*x2 + x2*x3)/(x0*x1),
 (x1*x5 + 1)/x2,
 (x1^2*x5 + x1*x3*x5 + x1 + x3)/(x0*x2),
 (x0*x1*x4*x5 + x0*x4 + x2)/(x1*x2),
 (x0*x1*x3*x4*x5 + x0*x3*x4 + x1*x2 + x2*x3)/(x0*x1*x2)]
b_matrix()[source]#

Return the \(B\) -matrix of self.

EXAMPLES:

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

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

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

sage: ClusterSeed(QuiverMutationType([['A',2],['B',2]])).b_matrix()
[ 0  1  0  0]
[-1  0  0  0]
[ 0  0  0  1]
[ 0  0 -2  0]
>>> from sage.all import *
>>> ClusterSeed(['A',Integer(4)]).b_matrix()
[ 0  1  0  0]
[-1  0 -1  0]
[ 0  1  0  1]
[ 0  0 -1  0]

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

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

>>> ClusterSeed(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]
b_matrix_class(depth=+Infinity, up_to_equivalence=True)[source]#

Return all \(B\)-matrices in the mutation class of self.

INPUT:

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

  • up_to_equivalence – (default: True) if True, only \(B\)-matrices up to equivalence are considered.

EXAMPLES:

b_matrix_class_iter(depth=+Infinity, up_to_equivalence=True)[source]#

Return an iterator through all \(B\)-matrices in the mutation class of self.

INPUT:

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

  • up_to_equivalence – (default: True) if True, only \(B\)-matrices up to equivalence are considered.

EXAMPLES:

A standard finite type example:

sage: S = ClusterSeed(['A',4])
sage: it = S.b_matrix_class_iter()
sage: for T in it: print(T)
[ 0  0  0  1]
[ 0  0  1  1]
[ 0 -1  0  0]
[-1 -1  0  0]
[ 0  0  0  1]
[ 0  0  1  0]
[ 0 -1  0  1]
[-1  0 -1  0]
[ 0  0  1  1]
[ 0  0  0 -1]
[-1  0  0  0]
[-1  1  0  0]
[ 0  0  0  1]
[ 0  0 -1  1]
[ 0  1  0 -1]
[-1 -1  1  0]
[ 0  0  0  1]
[ 0  0 -1  0]
[ 0  1  0 -1]
[-1  0  1  0]
[ 0  0  0 -1]
[ 0  0 -1  1]
[ 0  1  0 -1]
[ 1 -1  1  0]
>>> from sage.all import *
>>> S = ClusterSeed(['A',Integer(4)])
>>> it = S.b_matrix_class_iter()
>>> for T in it: print(T)
[ 0  0  0  1]
[ 0  0  1  1]
[ 0 -1  0  0]
[-1 -1  0  0]
[ 0  0  0  1]
[ 0  0  1  0]
[ 0 -1  0  1]
[-1  0 -1  0]
[ 0  0  1  1]
[ 0  0  0 -1]
[-1  0  0  0]
[-1  1  0  0]
[ 0  0  0  1]
[ 0  0 -1  1]
[ 0  1  0 -1]
[-1 -1  1  0]
[ 0  0  0  1]
[ 0  0 -1  0]
[ 0  1  0 -1]
[-1  0  1  0]
[ 0  0  0 -1]
[ 0  0 -1  1]
[ 0  1  0 -1]
[ 1 -1  1  0]

A finite type example with given depth:

sage: it = S.b_matrix_class_iter(depth=1)
sage: for T in it: print(T)
[ 0  0  0  1]
[ 0  0  1  1]
[ 0 -1  0  0]
[-1 -1  0  0]
[ 0  0  0  1]
[ 0  0  1  0]
[ 0 -1  0  1]
[-1  0 -1  0]
[ 0  0  1  1]
[ 0  0  0 -1]
[-1  0  0  0]
[-1  1  0  0]
>>> from sage.all import *
>>> it = S.b_matrix_class_iter(depth=Integer(1))
>>> for T in it: print(T)
[ 0  0  0  1]
[ 0  0  1  1]
[ 0 -1  0  0]
[-1 -1  0  0]
[ 0  0  0  1]
[ 0  0  1  0]
[ 0 -1  0  1]
[-1  0 -1  0]
[ 0  0  1  1]
[ 0  0  0 -1]
[-1  0  0  0]
[-1  1  0  0]

Finite type example not considered up to equivalence:

sage: S = ClusterSeed(['A',3])
sage: it = S.b_matrix_class_iter(up_to_equivalence=False)
sage: b_matrix_class = list(it)
sage: len(b_matrix_class)
14
sage: b_matrix_class[0]
[ 0  1  0]
[-1  0 -1]
[ 0  1  0]
>>> from sage.all import *
>>> S = ClusterSeed(['A',Integer(3)])
>>> it = S.b_matrix_class_iter(up_to_equivalence=False)
>>> b_matrix_class = list(it)
>>> len(b_matrix_class)
14
>>> b_matrix_class[Integer(0)]
[ 0  1  0]
[-1  0 -1]
[ 0  1  0]

Infinite (but finite mutation) type example:

sage: S = ClusterSeed(['A',[1,2],1])
sage: it = S.b_matrix_class_iter()
sage: for T in it: print(T)
[ 0  1  1]
[-1  0  1]
[-1 -1  0]
[ 0 -2  1]
[ 2  0 -1]
[-1  1  0]
>>> from sage.all import *
>>> S = ClusterSeed(['A',[Integer(1),Integer(2)],Integer(1)])
>>> it = S.b_matrix_class_iter()
>>> for T in it: print(T)
[ 0  1  1]
[-1  0  1]
[-1 -1  0]
[ 0 -2  1]
[ 2  0 -1]
[-1  1  0]

Infinite mutation type example:

sage: S = ClusterSeed(['E',10])
sage: it = S.b_matrix_class_iter(depth=3)
sage: len ([T for T in it])
266
>>> from sage.all import *
>>> S = ClusterSeed(['E',Integer(10)])
>>> it = S.b_matrix_class_iter(depth=Integer(3))
>>> len ([T for T in it])
266

For a cluster seed from an arbitrarily labelled digraph:

sage: dg = DiGraph([['a', 'b'], ['b', 'c']], format="list_of_edges")
sage: S = ClusterSeed(dg, frozen=['b'])
sage: S.b_matrix_class()
[
[ 0  0]  [ 0  0]  [0 0]
[ 0  0]  [ 0  0]  [0 0]
[-1  1], [-1 -1], [1 1]
]
>>> from sage.all import *
>>> dg = DiGraph([['a', 'b'], ['b', 'c']], format="list_of_edges")
>>> S = ClusterSeed(dg, frozen=['b'])
>>> S.b_matrix_class()
[
[ 0  0]  [ 0  0]  [0 0]
[ 0  0]  [ 0  0]  [0 0]
[-1  1], [-1 -1], [1 1]
]
c_matrix(show_warnings=True)[source]#

Return all c-vectors of self.

Warning

This method assumes the sign-coherence conjecture and that the input seed is sign-coherent (has an exchange matrix with columns of like signs). Otherwise, computational errors might arise.

EXAMPLES:

sage: S = ClusterSeed(['A',3]).principal_extension()
sage: S.mutate([2,1,2])
sage: S.c_matrix()
[ 1  0  0]
[ 0  0 -1]
[ 0 -1  0]

sage: S = ClusterSeed(['A',4])
sage: S.use_g_vectors(False); S.use_fpolys(False)
sage: S.use_c_vectors(False); S.use_d_vectors(False); S.track_mutations(False)
sage: S.c_matrix()
Traceback (most recent call last):
...
ValueError: Unable to calculate c-vectors. Need to use c vectors.
>>> from sage.all import *
>>> S = ClusterSeed(['A',Integer(3)]).principal_extension()
>>> S.mutate([Integer(2),Integer(1),Integer(2)])
>>> S.c_matrix()
[ 1  0  0]
[ 0  0 -1]
[ 0 -1  0]

>>> S = ClusterSeed(['A',Integer(4)])
>>> S.use_g_vectors(False); S.use_fpolys(False)
>>> S.use_c_vectors(False); S.use_d_vectors(False); S.track_mutations(False)
>>> S.c_matrix()
Traceback (most recent call last):
...
ValueError: Unable to calculate c-vectors. Need to use c vectors.
c_vector(k)[source]#

Return the k-th c-vector of self. It is obtained as the k-th column vector of the bottom part of the B-matrix of self.

Warning

This method assumes the sign-coherence conjecture and that the input seed is sign-coherent (has an exchange matrix with columns of like signs). Otherwise, computational errors might arise.

EXAMPLES:

sage: S = ClusterSeed(['A',3]).principal_extension()
sage: S.mutate([2,1,2])
sage: [S.c_vector(k) for k in range(3)]
[(1, 0, 0), (0, 0, -1), (0, -1, 0)]

sage: S = ClusterSeed(Matrix([[0,1],[-1,0],[1,0],[-1,1]])); S
A seed for a cluster algebra of rank 2 with 2 frozen variables
sage: S.c_vector(0)
(1, 0)

sage: S = ClusterSeed(Matrix([[0,1],[-1,0],[1,0],[-1,1]]))
sage: S.use_c_vectors(bot_is_c=True); S
A seed for a cluster algebra of rank 2 with 2 frozen variables
sage: S.c_vector(0)
(1, -1)
>>> from sage.all import *
>>> S = ClusterSeed(['A',Integer(3)]).principal_extension()
>>> S.mutate([Integer(2),Integer(1),Integer(2)])
>>> [S.c_vector(k) for k in range(Integer(3))]
[(1, 0, 0), (0, 0, -1), (0, -1, 0)]

>>> S = ClusterSeed(Matrix([[Integer(0),Integer(1)],[-Integer(1),Integer(0)],[Integer(1),Integer(0)],[-Integer(1),Integer(1)]])); S
A seed for a cluster algebra of rank 2 with 2 frozen variables
>>> S.c_vector(Integer(0))
(1, 0)

>>> S = ClusterSeed(Matrix([[Integer(0),Integer(1)],[-Integer(1),Integer(0)],[Integer(1),Integer(0)],[-Integer(1),Integer(1)]]))
>>> S.use_c_vectors(bot_is_c=True); S
A seed for a cluster algebra of rank 2 with 2 frozen variables
>>> S.c_vector(Integer(0))
(1, -1)
cluster()[source]#

Return a copy of the cluster of self.

EXAMPLES:

sage: S = ClusterSeed(['A',3])
sage: S.cluster()
[x0, x1, x2]

sage: S.mutate(1)
sage: S.cluster()
[x0, (x0*x2 + 1)/x1, x2]

sage: S.mutate(2)
sage: S.cluster()
[x0, (x0*x2 + 1)/x1, (x0*x2 + x1 + 1)/(x1*x2)]

sage: S.mutate([2,1])
sage: S.cluster()
[x0, x1, x2]
>>> from sage.all import *
>>> S = ClusterSeed(['A',Integer(3)])
>>> S.cluster()
[x0, x1, x2]

>>> S.mutate(Integer(1))
>>> S.cluster()
[x0, (x0*x2 + 1)/x1, x2]

>>> S.mutate(Integer(2))
>>> S.cluster()
[x0, (x0*x2 + 1)/x1, (x0*x2 + x1 + 1)/(x1*x2)]

>>> S.mutate([Integer(2),Integer(1)])
>>> S.cluster()
[x0, x1, x2]
cluster_class(depth=+Infinity, show_depth=False, up_to_equivalence=True)[source]#

Return the cluster class of self with respect to certain constraints.

INPUT:

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

  • return_depth – (default: False); if True, ignored if depth is set; returns the depth of the mutation class, i.e., the maximal distance from self of an element in the mutation class

  • up_to_equivalence – (default: True); if True, only clusters up to equivalence are considered.

EXAMPLES:

cluster_class_iter(depth=+Infinity, show_depth=False, up_to_equivalence=True)[source]#

Return an iterator through all clusters in the mutation class of self.

INPUT:

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

  • show_depth – (default: False) if True, ignored if depth is set; returns the depth of the mutation class, i.e., the maximal distance from self of an element in the mutation class

  • up_to_equivalence – (default: True) if True, only clusters up to equivalence are considered.

EXAMPLES:

A standard finite type example:

sage: S = ClusterSeed(['A',3])
sage: it = S.cluster_class_iter()
sage: cluster_class = list(it)
sage: len(cluster_class)
14
sage: cluster_class[0]
[x0, x1, x2]
>>> from sage.all import *
>>> S = ClusterSeed(['A',Integer(3)])
>>> it = S.cluster_class_iter()
>>> cluster_class = list(it)
>>> len(cluster_class)
14
>>> cluster_class[Integer(0)]
[x0, x1, x2]

A finite type example with given depth:

sage: it = S.cluster_class_iter(depth=1)
sage: for T in it: print(T)
[x0, x1, x2]
[x0, x1, (x1 + 1)/x2]
[x0, (x0*x2 + 1)/x1, x2]
[(x1 + 1)/x0, x1, x2]
>>> from sage.all import *
>>> it = S.cluster_class_iter(depth=Integer(1))
>>> for T in it: print(T)
[x0, x1, x2]
[x0, x1, (x1 + 1)/x2]
[x0, (x0*x2 + 1)/x1, x2]
[(x1 + 1)/x0, x1, x2]

A finite type example where the depth is returned while computing:

sage: it = S.cluster_class_iter(show_depth=True)
sage: _ = list(it)
Depth: 0     found: 1          Time: ... s
Depth: 1     found: 4          Time: ... s
Depth: 2     found: 9          Time: ... s
Depth: 3     found: 13         Time: ... s
Depth: 4     found: 14         Time: ... s
>>> from sage.all import *
>>> it = S.cluster_class_iter(show_depth=True)
>>> _ = list(it)
Depth: 0     found: 1          Time: ... s
Depth: 1     found: 4          Time: ... s
Depth: 2     found: 9          Time: ... s
Depth: 3     found: 13         Time: ... s
Depth: 4     found: 14         Time: ... s

Finite type examples not considered up to equivalence:

sage: it = S.cluster_class_iter(up_to_equivalence=False)
sage: len([T for T in it])
84

sage: it = ClusterSeed(['A',2]).cluster_class_iter(up_to_equivalence=False)
sage: cluster_class = list(it)
sage: len(cluster_class)
10
sage: cluster_class[0]
[x0, x1]
sage: cluster_class[-1]
[x1, x0]
>>> from sage.all import *
>>> it = S.cluster_class_iter(up_to_equivalence=False)
>>> len([T for T in it])
84

>>> it = ClusterSeed(['A',Integer(2)]).cluster_class_iter(up_to_equivalence=False)
>>> cluster_class = list(it)
>>> len(cluster_class)
10
>>> cluster_class[Integer(0)]
[x0, x1]
>>> cluster_class[-Integer(1)]
[x1, x0]

Infinite type examples:

sage: S = ClusterSeed(['A',[1,1],1])
sage: it = S.cluster_class_iter()
sage: next(it)
[x0, x1]
sage: next(it)
[x0, (x0^2 + 1)/x1]
sage: next(it)
[(x1^2 + 1)/x0, x1]
sage: next(it)
[(x0^4 + 2*x0^2 + x1^2 + 1)/(x0*x1^2), (x0^2 + 1)/x1]
sage: next(it)
[(x1^2 + 1)/x0, (x1^4 + x0^2 + 2*x1^2 + 1)/(x0^2*x1)]

sage: it = S.cluster_class_iter(depth=3)
sage: for T in it: print(T)
[x0, x1]
[x0, (x0^2 + 1)/x1]
[(x1^2 + 1)/x0, x1]
[(x0^4 + 2*x0^2 + x1^2 + 1)/(x0*x1^2), (x0^2 + 1)/x1]
[(x1^2 + 1)/x0, (x1^4 + x0^2 + 2*x1^2 + 1)/(x0^2*x1)]
[(x0^4 + 2*x0^2 + x1^2 + 1)/(x0*x1^2), (x0^6 + 3*x0^4 + 2*x0^2*x1^2 + x1^4 + 3*x0^2 + 2*x1^2 + 1)/(x0^2*x1^3)]
[(x1^6 + x0^4 + 2*x0^2*x1^2 + 3*x1^4 + 2*x0^2 + 3*x1^2 + 1)/(x0^3*x1^2), (x1^4 + x0^2 + 2*x1^2 + 1)/(x0^2*x1)]
>>> from sage.all import *
>>> S = ClusterSeed(['A',[Integer(1),Integer(1)],Integer(1)])
>>> it = S.cluster_class_iter()
>>> next(it)
[x0, x1]
>>> next(it)
[x0, (x0^2 + 1)/x1]
>>> next(it)
[(x1^2 + 1)/x0, x1]
>>> next(it)
[(x0^4 + 2*x0^2 + x1^2 + 1)/(x0*x1^2), (x0^2 + 1)/x1]
>>> next(it)
[(x1^2 + 1)/x0, (x1^4 + x0^2 + 2*x1^2 + 1)/(x0^2*x1)]

>>> it = S.cluster_class_iter(depth=Integer(3))
>>> for T in it: print(T)
[x0, x1]
[x0, (x0^2 + 1)/x1]
[(x1^2 + 1)/x0, x1]
[(x0^4 + 2*x0^2 + x1^2 + 1)/(x0*x1^2), (x0^2 + 1)/x1]
[(x1^2 + 1)/x0, (x1^4 + x0^2 + 2*x1^2 + 1)/(x0^2*x1)]
[(x0^4 + 2*x0^2 + x1^2 + 1)/(x0*x1^2), (x0^6 + 3*x0^4 + 2*x0^2*x1^2 + x1^4 + 3*x0^2 + 2*x1^2 + 1)/(x0^2*x1^3)]
[(x1^6 + x0^4 + 2*x0^2*x1^2 + 3*x1^4 + 2*x0^2 + 3*x1^2 + 1)/(x0^3*x1^2), (x1^4 + x0^2 + 2*x1^2 + 1)/(x0^2*x1)]

For a cluster seed from an arbitrarily labelled digraph:

sage: dg = DiGraph([['a', 'b'], ['b', 'c']], format="list_of_edges")
sage: S = ClusterSeed(dg, frozen=['b'])
sage: S.cluster_class()
[[a, c], [a, (b + 1)/c], [(b + 1)/a, c], [(b + 1)/a, (b + 1)/c]]

sage: S2 = ClusterSeed(dg, frozen=[])
sage: S2.cluster_class()[0]
[a, b, c]
>>> from sage.all import *
>>> dg = DiGraph([['a', 'b'], ['b', 'c']], format="list_of_edges")
>>> S = ClusterSeed(dg, frozen=['b'])
>>> S.cluster_class()
[[a, c], [a, (b + 1)/c], [(b + 1)/a, c], [(b + 1)/a, (b + 1)/c]]

>>> S2 = ClusterSeed(dg, frozen=[])
>>> S2.cluster_class()[Integer(0)]
[a, b, c]
cluster_index(cluster_str)[source]#

Return the index of a cluster if use_fpolys is on.

INPUT:

  • cluster_str – the string to look for in the cluster

OUTPUT:

An integer or None if the string is not a cluster variable

EXAMPLES:

sage: S = ClusterSeed(['A', 4], user_labels=['x', 'y', 'z', 'w']); S.mutate('x')
sage: S.cluster_index('x')
sage: S.cluster_index('(y+1)/x')
0
>>> from sage.all import *
>>> S = ClusterSeed(['A', Integer(4)], user_labels=['x', 'y', 'z', 'w']); S.mutate('x')
>>> S.cluster_index('x')
>>> S.cluster_index('(y+1)/x')
0
cluster_variable(k)[source]#

Generates a cluster variable using F-polynomials

EXAMPLES:

sage: S = ClusterSeed(['A',3])
sage: S.mutate([0,1])
sage: S.cluster_variable(0)
(x1 + 1)/x0
sage: S.cluster_variable(1)
(x0*x2 + x1 + 1)/(x0*x1)
>>> from sage.all import *
>>> S = ClusterSeed(['A',Integer(3)])
>>> S.mutate([Integer(0),Integer(1)])
>>> S.cluster_variable(Integer(0))
(x1 + 1)/x0
>>> S.cluster_variable(Integer(1))
(x0*x2 + x1 + 1)/(x0*x1)
coefficient(k)[source]#

Return the coefficient of self at index k, or vertex k if k is not an index.

EXAMPLES:

sage: S = ClusterSeed(['A',3]).principal_extension()
sage: S.mutate([2,1,2])
sage: [S.coefficient(k) for k in range(3)]
[y0, 1/y2, 1/y1]
>>> from sage.all import *
>>> S = ClusterSeed(['A',Integer(3)]).principal_extension()
>>> S.mutate([Integer(2),Integer(1),Integer(2)])
>>> [S.coefficient(k) for k in range(Integer(3))]
[y0, 1/y2, 1/y1]
coefficients()[source]#

Return all coefficients of self.

EXAMPLES:

sage: S = ClusterSeed(['A',3]).principal_extension()
sage: S.mutate([2,1,2])
sage: S.coefficients()
[y0, 1/y2, 1/y1]
>>> from sage.all import *
>>> S = ClusterSeed(['A',Integer(3)]).principal_extension()
>>> S.mutate([Integer(2),Integer(1),Integer(2)])
>>> S.coefficients()
[y0, 1/y2, 1/y1]
d_matrix(show_warnings=True)[source]#

Return the matrix of d-vectors of self.

EXAMPLES:

sage: S = ClusterSeed(['A',4]); S.d_matrix()
[-1  0  0  0]
[ 0 -1  0  0]
[ 0  0 -1  0]
[ 0  0  0 -1]
sage: S.mutate([1,2,1,0,1,3]); S.d_matrix()
[1 1 0 1]
[1 1 1 1]
[1 0 1 1]
[0 0 0 1]
>>> from sage.all import *
>>> S = ClusterSeed(['A',Integer(4)]); S.d_matrix()
[-1  0  0  0]
[ 0 -1  0  0]
[ 0  0 -1  0]
[ 0  0  0 -1]
>>> S.mutate([Integer(1),Integer(2),Integer(1),Integer(0),Integer(1),Integer(3)]); S.d_matrix()
[1 1 0 1]
[1 1 1 1]
[1 0 1 1]
[0 0 0 1]
d_vector(k)[source]#

Return the k-th d-vector of self. This is the exponent vector of the denominator of the k-th cluster variable.

EXAMPLES:

sage: S = ClusterSeed(['A',3])
sage: S.mutate([2,1,2])
sage: [S.d_vector(k) for k in range(3)]
[(-1, 0, 0), (0, 1, 1), (0, 1, 0)]
>>> from sage.all import *
>>> S = ClusterSeed(['A',Integer(3)])
>>> S.mutate([Integer(2),Integer(1),Integer(2)])
>>> [S.d_vector(k) for k in range(Integer(3))]
[(-1, 0, 0), (0, 1, 1), (0, 1, 0)]
exchangeable_part()[source]#

Return the restriction to the principal part (i.e. the exchangeable variables) of self.

EXAMPLES:

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

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

>>> T.exchangeable_part().quiver().digraph().edges(sort=True)
[(0, 1, (1, -1)), (2, 1, (1, -1))]
f_polynomial(k)[source]#

Return the k-th F-polynomial of self. It is obtained from the k-th cluster variable by setting all \(x_i\) to \(1\).

Warning

This method assumes the sign-coherence conjecture and that the input seed is sign-coherent (has an exchange matrix with columns of like signs). Otherwise, computational errors might arise.

EXAMPLES:

sage: S = ClusterSeed(['A',3]).principal_extension()
sage: S.mutate([2,1,2])
sage: [S.f_polynomial(k) for k in range(3)]
[1, y1*y2 + y2 + 1, y1 + 1]

sage: S = ClusterSeed(Matrix([[0,1],[-1,0],[1,0],[-1,1]]))
sage: S.use_c_vectors(bot_is_c=True); S
A seed for a cluster algebra of rank 2 with 2 frozen variables
sage: T = ClusterSeed(Matrix([[0,1],[-1,0]])).principal_extension(); T
A seed for a cluster algebra of rank 2 with principal coefficients
sage: S.mutate(0)
sage: T.mutate(0)
sage: S.f_polynomials()
[y0 + y1, 1]
sage: T.f_polynomials()
[y0 + 1, 1]
>>> from sage.all import *
>>> S = ClusterSeed(['A',Integer(3)]).principal_extension()
>>> S.mutate([Integer(2),Integer(1),Integer(2)])
>>> [S.f_polynomial(k) for k in range(Integer(3))]
[1, y1*y2 + y2 + 1, y1 + 1]

>>> S = ClusterSeed(Matrix([[Integer(0),Integer(1)],[-Integer(1),Integer(0)],[Integer(1),Integer(0)],[-Integer(1),Integer(1)]]))
>>> S.use_c_vectors(bot_is_c=True); S
A seed for a cluster algebra of rank 2 with 2 frozen variables
>>> T = ClusterSeed(Matrix([[Integer(0),Integer(1)],[-Integer(1),Integer(0)]])).principal_extension(); T
A seed for a cluster algebra of rank 2 with principal coefficients
>>> S.mutate(Integer(0))
>>> T.mutate(Integer(0))
>>> S.f_polynomials()
[y0 + y1, 1]
>>> T.f_polynomials()
[y0 + 1, 1]
f_polynomials()[source]#

Return all F-polynomials of self. These are obtained from the cluster variables by setting all \(x_i\)’s to \(1\).

Warning

This method assumes the sign-coherence conjecture and that the input seed is sign-coherent (has an exchange matrix with columns of like signs). Otherwise, computational errors might arise.

EXAMPLES:

sage: S = ClusterSeed(['A',3]).principal_extension()
sage: S.mutate([2,1,2])
sage: S.f_polynomials()
[1, y1*y2 + y2 + 1, y1 + 1]
>>> from sage.all import *
>>> S = ClusterSeed(['A',Integer(3)]).principal_extension()
>>> S.mutate([Integer(2),Integer(1),Integer(2)])
>>> S.f_polynomials()
[1, y1*y2 + y2 + 1, y1 + 1]
find_upper_bound(verbose=False)[source]#

Return the upper bound of the given cluster algebra as a quotient ring.

The upper bound is the intersection of the Laurent polynomial rings of the initial cluster and its neighboring clusters. As such, it always contains both the cluster algebra and the upper cluster algebra. This function uses the algorithm from [MM2015].

When the initial seed is totally coprime (for example, when the unfrozen part of the exchange matrix has full rank), the upper bound is equal to the upper cluster algebra by [BFZ2005].

Warning

The computation time grows rapidly with the size of the seed and the number of steps. For most seeds larger than four vertices, the algorithm may take an infeasible amount of time. Additionally, it will run forever without terminating whenever the upper bound is infinitely-generated (such as the example in [Spe2013]).

INPUT:

  • verbose – (default: False) if True, prints output during the computation.

EXAMPLES:

  • finite type:

    sage: S = ClusterSeed(['A',3])
    sage: S.find_upper_bound()
    Quotient of Multivariate Polynomial Ring in x0, x1, x2, x0p, x1p, x2p, z0
     over Rational Field
     by the ideal (x0*x0p - x1 - 1, x1*x1p - x0*x2 - 1, x2*x2p - x1 - 1,
                   x0*z0 - x2p, x1*z0 + z0 - x0p*x2p, x2*z0 - x0p,
                   x1p*z0 + z0 - x0p*x1p*x2p + x1 + 1)
    
    >>> from sage.all import *
    >>> S = ClusterSeed(['A',Integer(3)])
    >>> S.find_upper_bound()
    Quotient of Multivariate Polynomial Ring in x0, x1, x2, x0p, x1p, x2p, z0
     over Rational Field
     by the ideal (x0*x0p - x1 - 1, x1*x1p - x0*x2 - 1, x2*x2p - x1 - 1,
                   x0*z0 - x2p, x1*z0 + z0 - x0p*x2p, x2*z0 - x0p,
                   x1p*z0 + z0 - x0p*x1p*x2p + x1 + 1)
    
  • Markov:

    sage: B = matrix([[0,2,-2],[-2,0,2],[2,-2,0]])
    sage: S = ClusterSeed(B)
    sage: S.find_upper_bound()
    Quotient of Multivariate Polynomial Ring in x0, x1, x2, x0p, x1p, x2p, z0
     over Rational Field
     by the ideal (x0*x0p - x2^2 - x1^2, x1*x1p - x2^2 - x0^2, x2*x2p - x1^2 - x0^2,
                   x0p*x1p*x2p - x0*x1*x2p - x0*x2*x1p - x1*x2*x0p - 2*x0*x1*x2,
                   x0^3*z0 - x1p*x2p + x1*x2, x0*x1*z0 - x2p - x2,
                   x1^3*z0 - x0p*x2p + x0*x2, x0*x2*z0 - x1p - x1,
                   x1*x2*z0 - x0p - x0, x2^3*z0 - x0p*x1p + x0*x1)
    
    >>> from sage.all import *
    >>> B = matrix([[Integer(0),Integer(2),-Integer(2)],[-Integer(2),Integer(0),Integer(2)],[Integer(2),-Integer(2),Integer(0)]])
    >>> S = ClusterSeed(B)
    >>> S.find_upper_bound()
    Quotient of Multivariate Polynomial Ring in x0, x1, x2, x0p, x1p, x2p, z0
     over Rational Field
     by the ideal (x0*x0p - x2^2 - x1^2, x1*x1p - x2^2 - x0^2, x2*x2p - x1^2 - x0^2,
                   x0p*x1p*x2p - x0*x1*x2p - x0*x2*x1p - x1*x2*x0p - 2*x0*x1*x2,
                   x0^3*z0 - x1p*x2p + x1*x2, x0*x1*z0 - x2p - x2,
                   x1^3*z0 - x0p*x2p + x0*x2, x0*x2*z0 - x1p - x1,
                   x1*x2*z0 - x0p - x0, x2^3*z0 - x0p*x1p + x0*x1)
    
first_green_vertex()[source]#

Return the first green vertex of self.

A vertex is defined to be green if its c-vector has all non-positive entries. More information on green vertices can be found at [BDP2013]

EXAMPLES:

sage: ClusterSeed(['A',3]).principal_extension().first_green_vertex()
0

sage: ClusterSeed(['A',[3,3],1]).principal_extension().first_green_vertex()
0
>>> from sage.all import *
>>> ClusterSeed(['A',Integer(3)]).principal_extension().first_green_vertex()
0

>>> ClusterSeed(['A',[Integer(3),Integer(3)],Integer(1)]).principal_extension().first_green_vertex()
0
first_red_vertex()[source]#

Return the first red vertex of self.

A vertex is defined to be red if its c-vector has all non-negative entries. More information on red vertices can be found at [BDP2013].

EXAMPLES:

sage: ClusterSeed(['A',3]).principal_extension().first_red_vertex()

sage: ClusterSeed(['A',[3,3],1]).principal_extension().first_red_vertex()

sage: Q = ClusterSeed(['A',[3,3],1]).principal_extension()
sage: Q.mutate(1)
sage: Q.first_red_vertex()
1
>>> from sage.all import *
>>> ClusterSeed(['A',Integer(3)]).principal_extension().first_red_vertex()

>>> ClusterSeed(['A',[Integer(3),Integer(3)],Integer(1)]).principal_extension().first_red_vertex()

>>> Q = ClusterSeed(['A',[Integer(3),Integer(3)],Integer(1)]).principal_extension()
>>> Q.mutate(Integer(1))
>>> Q.first_red_vertex()
1
first_urban_renewal()[source]#

Return the first urban renewal vertex.

An urban renewal vertex is one in which there are two arrows pointing toward the vertex and two arrows pointing away.

EXAMPLES:

sage: G = ClusterSeed(['GR',[4,9]]); G.first_urban_renewal()
5
>>> from sage.all import *
>>> G = ClusterSeed(['GR',[Integer(4),Integer(9)]]); G.first_urban_renewal()
5
free_vertices()[source]#

Return the list of exchangeable vertices of self.

EXAMPLES:

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

sage: S = ClusterSeed(DiGraph([[5, 'b']]))
sage: S.free_vertices()
[5, 'b']
>>> from sage.all import *
>>> S = ClusterSeed(DiGraph([['a', 'b'], ['c', 'b'], ['c', 'd'], ['e', 'd']]),
...                         frozen=['b', 'd'])
>>> S.free_vertices()
['a', 'c', 'e']

>>> S = ClusterSeed(DiGraph([[Integer(5), 'b']]))
>>> S.free_vertices()
[5, 'b']
frozen_vertices()[source]#

Return the list of frozen vertices of self.

EXAMPLES:

sage: S = ClusterSeed(DiGraph([['a', 'b'], ['c', 'b'], ['c', 'd'], ['e', 'd']]),
....:                         frozen=['b', 'd'])
sage: sorted(S.frozen_vertices())
['b', 'd']
>>> from sage.all import *
>>> S = ClusterSeed(DiGraph([['a', 'b'], ['c', 'b'], ['c', 'd'], ['e', 'd']]),
...                         frozen=['b', 'd'])
>>> sorted(S.frozen_vertices())
['b', 'd']
g_matrix(show_warnings=True)[source]#

Return the matrix of all g-vectors of self. These are the degree vectors of the cluster variables after setting all \(y_i\)’s to \(0\).

Warning

This method assumes the sign-coherence conjecture and that the input seed is sign-coherent (has an exchange matrix with columns of like signs). Otherwise, computational errors might arise.

EXAMPLES:

sage: S = ClusterSeed(['A',3]).principal_extension()
sage: S.mutate([2,1,2])
sage: S.g_matrix()
[ 1  0  0]
[ 0  0 -1]
[ 0 -1  0]

sage: S = ClusterSeed(['A',3])
sage: S.mutate([0,1])
sage: S.g_matrix()
[-1 -1  0]
[ 1  0  0]
[ 0  0  1]

sage: S = ClusterSeed(['A',4])
sage: S.use_g_vectors(False); S.use_fpolys(False); S.g_matrix()
[1 0 0 0]
[0 1 0 0]
[0 0 1 0]
[0 0 0 1]

sage: S = ClusterSeed(['A',4])
sage: S.use_g_vectors(False); S.use_c_vectors(False); S.use_fpolys(False)
sage: S.track_mutations(False); S.g_matrix()
Traceback (most recent call last):
...
ValueError: Unable to calculate g-vectors. Need to use g vectors.
>>> from sage.all import *
>>> S = ClusterSeed(['A',Integer(3)]).principal_extension()
>>> S.mutate([Integer(2),Integer(1),Integer(2)])
>>> S.g_matrix()
[ 1  0  0]
[ 0  0 -1]
[ 0 -1  0]

>>> S = ClusterSeed(['A',Integer(3)])
>>> S.mutate([Integer(0),Integer(1)])
>>> S.g_matrix()
[-1 -1  0]
[ 1  0  0]
[ 0  0  1]

>>> S = ClusterSeed(['A',Integer(4)])
>>> S.use_g_vectors(False); S.use_fpolys(False); S.g_matrix()
[1 0 0 0]
[0 1 0 0]
[0 0 1 0]
[0 0 0 1]

>>> S = ClusterSeed(['A',Integer(4)])
>>> S.use_g_vectors(False); S.use_c_vectors(False); S.use_fpolys(False)
>>> S.track_mutations(False); S.g_matrix()
Traceback (most recent call last):
...
ValueError: Unable to calculate g-vectors. Need to use g vectors.
g_vector(k)[source]#

Return the k-th g-vector of self. This is the degree vector of the k-th cluster variable after setting all \(y_i\)’s to \(0\).

Warning

This method assumes the sign-coherence conjecture and that the input seed is sign-coherent (has an exchange matrix with columns of like signs). Otherwise, computational errors might arise.

EXAMPLES:

sage: S = ClusterSeed(['A',3]).principal_extension()
sage: S.mutate([2,1,2])
sage: [S.g_vector(k) for k in range(3)]
[(1, 0, 0), (0, 0, -1), (0, -1, 0)]
>>> from sage.all import *
>>> S = ClusterSeed(['A',Integer(3)]).principal_extension()
>>> S.mutate([Integer(2),Integer(1),Integer(2)])
>>> [S.g_vector(k) for k in range(Integer(3))]
[(1, 0, 0), (0, 0, -1), (0, -1, 0)]
get_upper_cluster_algebra_element(a)[source]#

Compute an element in the upper cluster algebra of \(B\) corresponding to the vector \(a \in \ZZ^n\).

See [LLM2014] for more details.

INPUT:

  • B – a skew-symmetric matrix. Must have the same number of columns as the length of the vectors in \(vd\).

  • a – a vector in \(\ZZ^n\) where \(n\) is the number of columns in \(B\).

OUTPUT:

Return an element in the upper cluster algebra. Depending on the input it may or may not be irreducible.

EXAMPLES:

sage: B = matrix([[0,3,-3],[-3,0,3],[3,-3,0],[1,0,0],[0,1,0],[0,0,1]])
sage: C = ClusterSeed(B)
sage: C.get_upper_cluster_algebra_element([1,1,0])
(x0^3*x2^3*x3*x4 + x2^6*x3 + x1^3*x2^3)/(x0*x1)
sage: C.get_upper_cluster_algebra_element([1,1,1])
x0^2*x1^2*x2^2*x3*x4*x5 + x0^2*x1^2*x2^2

sage: B = matrix([[0,3,0],[-3,0,3],[0,-3,0]])
sage: C = ClusterSeed(B)
sage: C.get_upper_cluster_algebra_element([1,1,0])
(x1^3*x2^3 + x0^3 + x2^3)/(x0*x1)
sage: C.get_upper_cluster_algebra_element([1,1,1])
(x0^3*x1^3 + x1^3*x2^3 + x0^3 + x2^3)/(x0*x1*x2)

sage: B = matrix([[0,2],[-3,0],[4,-5]])
sage: C = ClusterSeed(B)
sage: C.get_upper_cluster_algebra_element([1,1])
(x2^9 + x1^3*x2^5 + x0^2*x2^4)/(x0*x1)

sage: B = matrix([[0,3,-5],[-3,0,4],[5,-4,0]])
sage: C = ClusterSeed(B)
sage: C.get_upper_cluster_algebra_element([1,1,1])
x0^4*x1^2*x2^3 + x0^2*x1^3*x2^4
>>> from sage.all import *
>>> B = matrix([[Integer(0),Integer(3),-Integer(3)],[-Integer(3),Integer(0),Integer(3)],[Integer(3),-Integer(3),Integer(0)],[Integer(1),Integer(0),Integer(0)],[Integer(0),Integer(1),Integer(0)],[Integer(0),Integer(0),Integer(1)]])
>>> C = ClusterSeed(B)
>>> C.get_upper_cluster_algebra_element([Integer(1),Integer(1),Integer(0)])
(x0^3*x2^3*x3*x4 + x2^6*x3 + x1^3*x2^3)/(x0*x1)
>>> C.get_upper_cluster_algebra_element([Integer(1),Integer(1),Integer(1)])
x0^2*x1^2*x2^2*x3*x4*x5 + x0^2*x1^2*x2^2

>>> B = matrix([[Integer(0),Integer(3),Integer(0)],[-Integer(3),Integer(0),Integer(3)],[Integer(0),-Integer(3),Integer(0)]])
>>> C = ClusterSeed(B)
>>> C.get_upper_cluster_algebra_element([Integer(1),Integer(1),Integer(0)])
(x1^3*x2^3 + x0^3 + x2^3)/(x0*x1)
>>> C.get_upper_cluster_algebra_element([Integer(1),Integer(1),Integer(1)])
(x0^3*x1^3 + x1^3*x2^3 + x0^3 + x2^3)/(x0*x1*x2)

>>> B = matrix([[Integer(0),Integer(2)],[-Integer(3),Integer(0)],[Integer(4),-Integer(5)]])
>>> C = ClusterSeed(B)
>>> C.get_upper_cluster_algebra_element([Integer(1),Integer(1)])
(x2^9 + x1^3*x2^5 + x0^2*x2^4)/(x0*x1)

>>> B = matrix([[Integer(0),Integer(3),-Integer(5)],[-Integer(3),Integer(0),Integer(4)],[Integer(5),-Integer(4),Integer(0)]])
>>> C = ClusterSeed(B)
>>> C.get_upper_cluster_algebra_element([Integer(1),Integer(1),Integer(1)])
x0^4*x1^2*x2^3 + x0^2*x1^3*x2^4
greedy(a1, a2, algorithm='by_recursion')[source]#

Return the greedy element \(x[a_1,a_2]\) assuming that self is rank two.

The third input can be 'by_recursion', 'by_combinatorics', or 'just_numbers' to specify if the user wants the element computed by the recurrence, combinatorial formula, or wants to set \(x_1\) and \(x_2\) to be one.

See [LLZ2014] for more details.

EXAMPLES:

sage: S = ClusterSeed(['R2', [3, 3]])
sage: S.greedy(4, 4)
(x0^12 + x1^12 + 4*x0^9 + 4*x1^9 + 6*x0^6
  + 4*x0^3*x1^3 + 6*x1^6 + 4*x0^3 + 4*x1^3 + 1)/(x0^4*x1^4)
sage: S.greedy(4, 4, 'by_combinatorics')
(x0^12 + x1^12 + 4*x0^9 + 4*x1^9 + 6*x0^6
  + 4*x0^3*x1^3 + 6*x1^6 + 4*x0^3 + 4*x1^3 + 1)/(x0^4*x1^4)
sage: S.greedy(4, 4, 'just_numbers')
35
sage: S = ClusterSeed(['R2', [2, 2]])
sage: S.greedy(1, 2)
(x0^4 + 2*x0^2 + x1^2 + 1)/(x0*x1^2)
sage: S.greedy(1, 2, 'by_combinatorics')
(x0^4 + 2*x0^2 + x1^2 + 1)/(x0*x1^2)
>>> from sage.all import *
>>> S = ClusterSeed(['R2', [Integer(3), Integer(3)]])
>>> S.greedy(Integer(4), Integer(4))
(x0^12 + x1^12 + 4*x0^9 + 4*x1^9 + 6*x0^6
  + 4*x0^3*x1^3 + 6*x1^6 + 4*x0^3 + 4*x1^3 + 1)/(x0^4*x1^4)
>>> S.greedy(Integer(4), Integer(4), 'by_combinatorics')
(x0^12 + x1^12 + 4*x0^9 + 4*x1^9 + 6*x0^6
  + 4*x0^3*x1^3 + 6*x1^6 + 4*x0^3 + 4*x1^3 + 1)/(x0^4*x1^4)
>>> S.greedy(Integer(4), Integer(4), 'just_numbers')
35
>>> S = ClusterSeed(['R2', [Integer(2), Integer(2)]])
>>> S.greedy(Integer(1), Integer(2))
(x0^4 + 2*x0^2 + x1^2 + 1)/(x0*x1^2)
>>> S.greedy(Integer(1), Integer(2), 'by_combinatorics')
(x0^4 + 2*x0^2 + x1^2 + 1)/(x0*x1^2)
green_vertices()[source]#

Return the list of green vertices of self.

A vertex is defined to be green if its c-vector has all non-positive entries. More information on green vertices can be found at [BDP2013]

OUTPUT:

The green vertices as a list of integers.

EXAMPLES:

sage: ClusterSeed(['A',3]).principal_extension().green_vertices()
[0, 1, 2]

sage: ClusterSeed(['A',[3,3],1]).principal_extension().green_vertices()
[0, 1, 2, 3, 4, 5]
>>> from sage.all import *
>>> ClusterSeed(['A',Integer(3)]).principal_extension().green_vertices()
[0, 1, 2]

>>> ClusterSeed(['A',[Integer(3),Integer(3)],Integer(1)]).principal_extension().green_vertices()
[0, 1, 2, 3, 4, 5]
ground_field()[source]#

Return the ground field of the cluster of self.

EXAMPLES:

sage: S = ClusterSeed(['A',3])
sage: S.ground_field()
Multivariate Polynomial Ring in x0, x1, x2, y0, y1, y2 over Rational Field
>>> from sage.all import *
>>> S = ClusterSeed(['A',Integer(3)])
>>> S.ground_field()
Multivariate Polynomial Ring in x0, x1, x2, y0, y1, y2 over Rational Field
highest_degree_denominator(filter=None)[source]#

Return the vertex of the cluster polynomial with highest degree in the denominator.

INPUT:

  • filter – a list or iterable

OUTPUT:

An integer.

EXAMPLES:

sage: B = matrix([[0,-1,0,-1,1,1], [1,0,1,0,-1,-1], [0,-1,0,-1,1,1],
....:             [1,0,1,0,-1,-1], [-1,1,-1,1,0,0], [-1,1,-1,1,0,0]])
sage: C = ClusterSeed(B).principal_extension(); C.mutate([0,1,2,4,3,2,5,4,3])
sage: C.highest_degree_denominator()
5
>>> from sage.all import *
>>> B = matrix([[Integer(0),-Integer(1),Integer(0),-Integer(1),Integer(1),Integer(1)], [Integer(1),Integer(0),Integer(1),Integer(0),-Integer(1),-Integer(1)], [Integer(0),-Integer(1),Integer(0),-Integer(1),Integer(1),Integer(1)],
...             [Integer(1),Integer(0),Integer(1),Integer(0),-Integer(1),-Integer(1)], [-Integer(1),Integer(1),-Integer(1),Integer(1),Integer(0),Integer(0)], [-Integer(1),Integer(1),-Integer(1),Integer(1),Integer(0),Integer(0)]])
>>> C = ClusterSeed(B).principal_extension(); C.mutate([Integer(0),Integer(1),Integer(2),Integer(4),Integer(3),Integer(2),Integer(5),Integer(4),Integer(3)])
>>> C.highest_degree_denominator()
5
interact(fig_size=1, circular=True)[source]#

Start an interactive window for cluster seed mutations.

Only in Jupyter notebook mode.

INPUT:

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

  • circular – (default: True) if True, the circular plot is chosen, otherwise >>spring<< is used.

is_acyclic()[source]#

Return True iff self is acyclic (i.e., if the underlying quiver is acyclic).

EXAMPLES:

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

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

sage: ClusterSeed([[0,1],[1,2],[2,0]]).is_acyclic()
False
>>> from sage.all import *
>>> ClusterSeed(['A',Integer(4)]).is_acyclic()
True

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

>>> ClusterSeed([[Integer(0),Integer(1)],[Integer(1),Integer(2)],[Integer(2),Integer(0)]]).is_acyclic()
False
is_bipartite(return_bipartition=False)[source]#

Return True iff self is bipartite (i.e., if the underlying quiver is bipartite).

INPUT:

  • return_bipartition – (default: False) if True, the bipartition is returned in the case of self being bipartite.

EXAMPLES:

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

sage: ClusterSeed(['A',[4,3],1]).is_bipartite()
False
>>> from sage.all import *
>>> ClusterSeed(['A',[Integer(3),Integer(3)],Integer(1)]).is_bipartite()
True

>>> ClusterSeed(['A',[Integer(4),Integer(3)],Integer(1)]).is_bipartite()
False
is_finite()[source]#

Return True if self is of finite type.

EXAMPLES:

sage: S = ClusterSeed(['A',3])
sage: S.is_finite()
True

sage: S = ClusterSeed(['A',[2,2],1])
sage: S.is_finite()
False
>>> from sage.all import *
>>> S = ClusterSeed(['A',Integer(3)])
>>> S.is_finite()
True

>>> S = ClusterSeed(['A',[Integer(2),Integer(2)],Integer(1)])
>>> S.is_finite()
False
is_mutation_finite(nr_of_checks=None, return_path=False)[source]#

Return True if self is of finite mutation type.

INPUT:

  • nr_of_checks – (default: None) number of mutations applied. Standard is 500 times the 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 cluster seed is mutation infinite if and only if every \(b_{ij}*b_{ji} > -4\). Thus, we apply random mutations in random directions

Warning

  • Uses a non-deterministic method by random mutations in various directions.

  • In theory, it can return a wrong True.

EXAMPLES:

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

sage: S = ClusterSeed([(0,1),(1,2),(2,3),(3,4),(4,5),(5,6),(6,7),(7,8),(2,9)])
sage: S.is_mutation_finite()
False
>>> from sage.all import *
>>> S = ClusterSeed(['A',Integer(10)])
>>> S._mutation_type = None
>>> S.is_mutation_finite()
True

>>> S = ClusterSeed([(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))])
>>> S.is_mutation_finite()
False
m()[source]#

Return the number of frozen variables of self.

EXAMPLES:

sage: S = ClusterSeed(['A',3])
sage: S.n()
3

sage: S.m()
0

sage: S = S.principal_extension()
sage: S.m()
3
>>> from sage.all import *
>>> S = ClusterSeed(['A',Integer(3)])
>>> S.n()
3

>>> S.m()
0

>>> S = S.principal_extension()
>>> S.m()
3
most_decreased_denominator_after_mutation()[source]#

Return the vertex that will produce the most decrease in denominator degrees after mutation

EXAMPLES:

sage: S = ClusterSeed(['A',5])
sage: S.mutate([0,2,3,1,2,3,1,2,0,2,3])
sage: S.most_decreased_denominator_after_mutation()
2
>>> from sage.all import *
>>> S = ClusterSeed(['A',Integer(5)])
>>> S.mutate([Integer(0),Integer(2),Integer(3),Integer(1),Integer(2),Integer(3),Integer(1),Integer(2),Integer(0),Integer(2),Integer(3)])
>>> S.most_decreased_denominator_after_mutation()
2
most_decreased_edge_after_mutation()[source]#

Return the vertex that will produce the least degrees after mutation

EXAMPLES:

sage: S = ClusterSeed(['A',5])
sage: S.mutate([0,2,3,1,2,3,1,2,0,2,3])
sage: S.most_decreased_edge_after_mutation()
2
>>> from sage.all import *
>>> S = ClusterSeed(['A',Integer(5)])
>>> S.mutate([Integer(0),Integer(2),Integer(3),Integer(1),Integer(2),Integer(3),Integer(1),Integer(2),Integer(0),Integer(2),Integer(3)])
>>> S.most_decreased_edge_after_mutation()
2
mutate(sequence, inplace=True, input_type=None)[source]#

Mutate self at a vertex or a sequence of vertices.

INPUT:

  • sequence – a vertex of self, an iterator of vertices of self, a function which takes in the ClusterSeed and returns a vertex or an iterator of vertices, or a string representing a type of vertices to mutate

  • inplace – (default: True) if False, the result is returned, otherwise self is modified

  • input_type – (default: None) indicates the type of data contained in the sequence

Possible values for vertex types in sequence are:

  • "first_source": mutates at first found source vertex,

  • "sources": mutates at all sources,

  • "first_sink": mutates at first sink,

  • "sinks": mutates at all sink vertices,

  • "green": mutates at the first green vertex,

  • "red": mutates at the first red vertex,

  • "urban_renewal" or "urban": mutates at first urban renewal vertex,

  • "all_urban_renewals" or "all_urban": mutates at all urban renewal vertices.

For input_type, if no value is given, preference will be given to vertex names, then indices, then cluster variables. If all input is not of the same type, an error is given. Possible values for input_type are:

  • "vertices": interprets the input sequence as vertices

  • "indices": interprets the input sequence as indices

  • "cluster_vars": interprets the input sequence as cluster variables this must be selected if inputting a sequence of cluster variables.

EXAMPLES:

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

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

sage: T = S.mutate(0, inplace=False); T
A seed for a cluster algebra of rank 4 of type ['A', 4]

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

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

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

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

sage: Q = ClusterSeed(['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: def last_vertex(self): return self._n - 1
sage: Q.mutate(last_vertex); Q.b_matrix()
[ 0 -1  0]
[ 1  0 -1]
[ 0  1  0]

sage: S = ClusterSeed(['A', 4], user_labels=['a', 'b', 'c', 'd'])
sage: S.mutate('a'); S.mutate('(b+1)/a')
sage: S.cluster()
[a, b, c, d]

sage: S = ClusterSeed(['A', 4], user_labels=['a', 'b', 'c'])
Traceback (most recent call last):
...
ValueError: the number of user-defined labels is not
 the number of exchangeable and frozen variables

sage: S = ClusterSeed(['A', 4], user_labels=['x', 'y', 'w', 'z'])
sage: S.mutate('x')
sage: S.cluster()
[(y + 1)/x, y, w, z]
sage: S.mutate('(y+1)/x')
sage: S.cluster()
[x, y, w, z]
sage: S.mutate('y')
sage: S.cluster()
[x, (x*w + 1)/y, w, z]
sage: S.mutate('(x*w+1)/y')
sage: S.cluster()
[x, y, w, z]

sage: S = ClusterSeed(['A', 4], user_labels=[[1, 2], [2, 3], [4, 5], [5, 6]])
sage: S.cluster()
[x_1_2, x_2_3, x_4_5, x_5_6]
sage: S.mutate('[1,2]')
sage: S.cluster()
[(x_2_3 + 1)/x_1_2, x_2_3, x_4_5, x_5_6]

sage: S = ClusterSeed(['A', 4], user_labels=[[1, 2], [2, 3], [4, 5], [5, 6]],
....:                 user_labels_prefix='P');
sage: S.cluster()
[P_1_2, P_2_3, P_4_5, P_5_6]
sage: S.mutate('[1,2]')
sage: S.cluster()
[(P_2_3 + 1)/P_1_2, P_2_3, P_4_5, P_5_6]
sage: S.mutate('P_4_5')
sage: S.cluster()
[(P_2_3 + 1)/P_1_2, P_2_3, (P_2_3*P_5_6 + 1)/P_4_5, P_5_6]

sage: S = ClusterSeed(['A', 4])
sage: S.mutate([0, 1, 0, 1, 0, 2, 1])
sage: T = ClusterSeed(S)
sage: S.use_fpolys(False)
sage: S.use_g_vectors(False)
sage: S.use_c_vectors(False)
sage: S._C
sage: S._G
sage: S._F
sage: S.g_matrix()
[ 0 -1  0  0]
[ 1  1  1  0]
[ 0  0 -1  0]
[ 0  0  1  1]
sage: S.c_matrix()
[ 1 -1  0  0]
[ 1  0  0  0]
[ 1  0 -1  1]
[ 0  0  0  1]
sage: S.f_polynomials() == T.f_polynomials()
True

sage: S.cluster() == T.cluster()
True
sage: S._mut_path
[0, 1, 0, 1, 0, 2, 1]

sage: S = ClusterSeed(DiGraph([[1, 2], [2, 'c']]))
sage: S.mutate(1)
Input can be ambiguously interpreted as both vertices and indices.
 Mutating at vertices by default.
sage: S.cluster()
[(x2 + 1)/x1, x2, c]
sage: S.mutate(1, input_type="indices")
sage: S.cluster()
[(x2 + 1)/x1, (x2*c + x1 + c)/(x1*x2), c]

sage: S = ClusterSeed(DiGraph([['a', 'b'], ['c', 'b'], ['d', 'b']]))
sage: S.mutate(['a', 'b', 'a', 'b', 'a'])
sage: S.cluster()
[b, a, c, d]
sage: S.mutate('a')
Input can be ambiguously interpreted as both vertices and cluster variables.
 Mutating at vertices by default.
sage: S.cluster()
[(a*c*d + 1)/b, a, c, d]
sage: S.mutate('a', input_type="cluster_vars")
sage: S.cluster()
[(a*c*d + 1)/b, (a*c*d + b + 1)/(a*b), c, d]
sage: S.mutate(['(a*c*d + 1)/b', 'd'])
sage: S.cluster()
[(b + 1)/a, (a*c*d + b + 1)/(a*b), c, (a*c*d + b^2 + 2*b + 1)/(a*b*d)]

sage: S = ClusterSeed(DiGraph([[5, 'b']]))
sage: S.mutate(5)
sage: S.cluster()
[(b + 1)/x5, b]
sage: S.mutate([5])
sage: S.cluster()
[x5, b]
sage: S.mutate(0)
sage: S.cluster()
[(b + 1)/x5, b]

sage: S = ClusterSeed(DiGraph([[1, 2]]))
sage: S.cluster()
[x1, x2]
sage: S.mutate(1)
Input can be ambiguously interpreted as both vertices and indices.
 Mutating at vertices by default.
sage: S.cluster()
[(x2 + 1)/x1, x2]

sage: S = ClusterSeed(DiGraph([[-1, 0], [0, 1]]))
sage: S.cluster()
[xneg1, x0, x1]
sage: S.mutate(-1);S.cluster()
[(x0 + 1)/xneg1, x0, x1]
sage: S.mutate(0, input_type='vertices');S.cluster()
[(x0 + 1)/xneg1, (x0*x1 + xneg1 + x1)/(xneg1*x0), x1]
>>> from sage.all import *
>>> S = ClusterSeed(['A',Integer(4)]); S.b_matrix()
[ 0  1  0  0]
[-1  0 -1  0]
[ 0  1  0  1]
[ 0  0 -1  0]

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

>>> T = S.mutate(Integer(0), inplace=False); T
A seed for a cluster algebra of rank 4 of type ['A', 4]

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

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

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

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

>>> Q = ClusterSeed(['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]

>>> def last_vertex(self): return self._n - Integer(1)
>>> Q.mutate(last_vertex); Q.b_matrix()
[ 0 -1  0]
[ 1  0 -1]
[ 0  1  0]

>>> S = ClusterSeed(['A', Integer(4)], user_labels=['a', 'b', 'c', 'd'])
>>> S.mutate('a'); S.mutate('(b+1)/a')
>>> S.cluster()
[a, b, c, d]

>>> S = ClusterSeed(['A', Integer(4)], user_labels=['a', 'b', 'c'])
Traceback (most recent call last):
...
ValueError: the number of user-defined labels is not
 the number of exchangeable and frozen variables

>>> S = ClusterSeed(['A', Integer(4)], user_labels=['x', 'y', 'w', 'z'])
>>> S.mutate('x')
>>> S.cluster()
[(y + 1)/x, y, w, z]
>>> S.mutate('(y+1)/x')
>>> S.cluster()
[x, y, w, z]
>>> S.mutate('y')
>>> S.cluster()
[x, (x*w + 1)/y, w, z]
>>> S.mutate('(x*w+1)/y')
>>> S.cluster()
[x, y, w, z]

>>> S = ClusterSeed(['A', Integer(4)], user_labels=[[Integer(1), Integer(2)], [Integer(2), Integer(3)], [Integer(4), Integer(5)], [Integer(5), Integer(6)]])
>>> S.cluster()
[x_1_2, x_2_3, x_4_5, x_5_6]
>>> S.mutate('[1,2]')
>>> S.cluster()
[(x_2_3 + 1)/x_1_2, x_2_3, x_4_5, x_5_6]

>>> S = ClusterSeed(['A', Integer(4)], user_labels=[[Integer(1), Integer(2)], [Integer(2), Integer(3)], [Integer(4), Integer(5)], [Integer(5), Integer(6)]],
...                 user_labels_prefix='P');
>>> S.cluster()
[P_1_2, P_2_3, P_4_5, P_5_6]
>>> S.mutate('[1,2]')
>>> S.cluster()
[(P_2_3 + 1)/P_1_2, P_2_3, P_4_5, P_5_6]
>>> S.mutate('P_4_5')
>>> S.cluster()
[(P_2_3 + 1)/P_1_2, P_2_3, (P_2_3*P_5_6 + 1)/P_4_5, P_5_6]

>>> S = ClusterSeed(['A', Integer(4)])
>>> S.mutate([Integer(0), Integer(1), Integer(0), Integer(1), Integer(0), Integer(2), Integer(1)])
>>> T = ClusterSeed(S)
>>> S.use_fpolys(False)
>>> S.use_g_vectors(False)
>>> S.use_c_vectors(False)
>>> S._C
>>> S._G
>>> S._F
>>> S.g_matrix()
[ 0 -1  0  0]
[ 1  1  1  0]
[ 0  0 -1  0]
[ 0  0  1  1]
>>> S.c_matrix()
[ 1 -1  0  0]
[ 1  0  0  0]
[ 1  0 -1  1]
[ 0  0  0  1]
>>> S.f_polynomials() == T.f_polynomials()
True

>>> S.cluster() == T.cluster()
True
>>> S._mut_path
[0, 1, 0, 1, 0, 2, 1]

>>> S = ClusterSeed(DiGraph([[Integer(1), Integer(2)], [Integer(2), 'c']]))
>>> S.mutate(Integer(1))
Input can be ambiguously interpreted as both vertices and indices.
 Mutating at vertices by default.
>>> S.cluster()
[(x2 + 1)/x1, x2, c]
>>> S.mutate(Integer(1), input_type="indices")
>>> S.cluster()
[(x2 + 1)/x1, (x2*c + x1 + c)/(x1*x2), c]

>>> S = ClusterSeed(DiGraph([['a', 'b'], ['c', 'b'], ['d', 'b']]))
>>> S.mutate(['a', 'b', 'a', 'b', 'a'])
>>> S.cluster()
[b, a, c, d]
>>> S.mutate('a')
Input can be ambiguously interpreted as both vertices and cluster variables.
 Mutating at vertices by default.
>>> S.cluster()
[(a*c*d + 1)/b, a, c, d]
>>> S.mutate('a', input_type="cluster_vars")
>>> S.cluster()
[(a*c*d + 1)/b, (a*c*d + b + 1)/(a*b), c, d]
>>> S.mutate(['(a*c*d + 1)/b', 'd'])
>>> S.cluster()
[(b + 1)/a, (a*c*d + b + 1)/(a*b), c, (a*c*d + b^2 + 2*b + 1)/(a*b*d)]

>>> S = ClusterSeed(DiGraph([[Integer(5), 'b']]))
>>> S.mutate(Integer(5))
>>> S.cluster()
[(b + 1)/x5, b]
>>> S.mutate([Integer(5)])
>>> S.cluster()
[x5, b]
>>> S.mutate(Integer(0))
>>> S.cluster()
[(b + 1)/x5, b]

>>> S = ClusterSeed(DiGraph([[Integer(1), Integer(2)]]))
>>> S.cluster()
[x1, x2]
>>> S.mutate(Integer(1))
Input can be ambiguously interpreted as both vertices and indices.
 Mutating at vertices by default.
>>> S.cluster()
[(x2 + 1)/x1, x2]

>>> S = ClusterSeed(DiGraph([[-Integer(1), Integer(0)], [Integer(0), Integer(1)]]))
>>> S.cluster()
[xneg1, x0, x1]
>>> S.mutate(-Integer(1));S.cluster()
[(x0 + 1)/xneg1, x0, x1]
>>> S.mutate(Integer(0), input_type='vertices');S.cluster()
[(x0 + 1)/xneg1, (x0*x1 + xneg1 + x1)/(xneg1*x0), x1]
mutation_analysis(options=['all'], filter=None)[source]#

Runs an analysis of all potential mutation options. Note that this might take a long time on large seeds.

Note

Edges are only returned if we have a non-valued quiver. Green and red vertices are only returned if the cluster is principal.

INPUT:

  • options – (default: ['all']) a list of mutation options.

  • filter – (default: None) A vertex or interval of vertices to limit our search to

Possible options are:

  • "all" – All options below

  • "edges" – Number of edges (works with skew-symmetric quivers)

  • "edge_diff" – Edges added/deleted (works with skew-symmetric quivers)

  • "green_vertices" – List of green vertices (works with principals)

  • "green_vertices_diff" – Green vertices added/removed (works with principals)

  • "red_vertices" – List of red vertices (works with principals)

  • "red_vertices_diff" – Red vertices added/removed (works with principals)

  • "urban_renewals" – List of urban renewal vertices

  • "urban_renewals_diff" – Urban renewal vertices added/removed

  • "sources" – List of source vertices

  • "sources_diff" – Source vertices added/removed

  • "sinks" – List of sink vertices

  • "sinks_diff" – Sink vertices added/removed

  • "denominators" – List of all denominators of the cluster variables

OUTPUT:

Outputs a dictionary indexed by the vertex numbers. Each vertex will itself also be a dictionary with each desired option included as a key in the dictionary. As an example you would get something similar to: {0: {'edges': 1}, 1: {'edges': 2}}. This represents that if you were to do a mutation at the current seed then mutating at vertex 0 would result in a quiver with 1 edge and mutating at vertex 0 would result in a quiver with 2 edges.

EXAMPLES:

sage: B = [[0, 4, 0, -1],[-4,0, 3, 0],[0, -3, 0, 1],[1, 0, -1, 0]]
sage: S = ClusterSeed(matrix(B)); S.mutate([2,3,1,2,1,3,0,2])
sage: S.mutation_analysis()
{0: {'d_matrix': [ 0  0  1  0]
                 [ 0 -1  0  0]
                 [ 0  0  0 -1]
                 [-1  0  0  0],
     'denominators': [1, 1, x0, 1],
     'edge_diff': 6,
     'edges': 13,
     'green_vertices': [0, 1, 3],
     'green_vertices_diff': {'added': [0], 'removed': []},
     'red_vertices': [2],
     'red_vertices_diff': {'added': [], 'removed': [0]},
     'sinks': [],
     'sinks_diff': {'added': [], 'removed': [2]},
     'sources': [],
     'sources_diff': {'added': [], 'removed': []},
     'urban_renewals': [],
     'urban_renewals_diff': {'added': [], 'removed': []}},
 1: {'d_matrix': [ 1  4  1  0]
                 [ 0  1  0  0]
                 [ 0  0  0 -1]
                 [ 1  4  0  0],
     'denominators': [x0*x3, x0^4*x1*x3^4, x0, 1],
     'edge_diff': 2,
     'edges': 9,
     'green_vertices': [0, 3],
     'green_vertices_diff': {'added': [0], 'removed': [1]},
     'red_vertices': [1, 2],
     'red_vertices_diff': {'added': [1], 'removed': [0]},
     'sinks': [2],
     'sinks_diff': {'added': [], 'removed': []},
     'sources': [],
     'sources_diff': {'added': [], 'removed': []},
     'urban_renewals': [],
     'urban_renewals_diff': {'added': [], 'removed': []}},
 2: {'d_matrix': [ 1  0  0  0]
                 [ 0 -1  0  0]
                 [ 0  0  0 -1]
                 [ 1  0  1  0],
     'denominators': [x0*x3, 1, x3, 1],
     'edge_diff': 0,
     'edges': 7,
     'green_vertices': [1, 2, 3],
     'green_vertices_diff': {'added': [2], 'removed': []},
     'red_vertices': [0],
     'red_vertices_diff': {'added': [], 'removed': [2]},
     'sinks': [],
     'sinks_diff': {'added': [], 'removed': [2]},
     'sources': [2],
     'sources_diff': {'added': [2], 'removed': []},
     'urban_renewals': [],
     'urban_renewals_diff': {'added': [], 'removed': []}},
 3: {'d_matrix': [ 1  0  1  1]
                 [ 0 -1  0  0]
                 [ 0  0  0  1]
                 [ 1  0  0  1],
     'denominators': [x0*x3, 1, x0, x0*x2*x3],
     'edge_diff': -1,
     'edges': 6,
     'green_vertices': [1],
     'green_vertices_diff': {'added': [], 'removed': [3]},
     'red_vertices': [0, 2, 3],
     'red_vertices_diff': {'added': [3], 'removed': []},
     'sinks': [2],
     'sinks_diff': {'added': [], 'removed': []},
     'sources': [1],
     'sources_diff': {'added': [1], 'removed': []},
     'urban_renewals': [],
     'urban_renewals_diff': {'added': [], 'removed': []}}}

sage: S = ClusterSeed(['A',3]).principal_extension()
sage: S.mutation_analysis()
{0: {'d_matrix': [ 1  0  0]
                 [ 0 -1  0]
                 [ 0  0 -1],
     'denominators': [x0, 1, 1],
     'green_vertices': [1, 2],
     'green_vertices_diff': {'added': [], 'removed': [0]},
     'red_vertices': [0],
     'red_vertices_diff': {'added': [0], 'removed': []},
     'sinks': [],
     'sinks_diff': {'added': [], 'removed': [1]},
     'sources': [4, 5],
     'sources_diff': {'added': [], 'removed': [3]},
     'urban_renewals': [],
     'urban_renewals_diff': {'added': [], 'removed': []}},
 1: {'d_matrix': [-1  0  0]
                 [ 0  1  0]
                 [ 0  0 -1],
     'denominators': [1, x1, 1],
     'green_vertices': [0, 2],
     'green_vertices_diff': {'added': [], 'removed': [1]},
     'red_vertices': [1],
     'red_vertices_diff': {'added': [1], 'removed': []},
     'sinks': [0, 2, 4],
     'sinks_diff': {'added': [0, 2, 4], 'removed': [1]},
     'sources': [1, 3, 5],
     'sources_diff': {'added': [1], 'removed': [4]},
     'urban_renewals': [],
     'urban_renewals_diff': {'added': [], 'removed': []}},
 2: {'d_matrix': [-1  0  0]
                 [ 0 -1  0]
                 [ 0  0  1],
     'denominators': [1, 1, x2],
     'green_vertices': [0, 1],
     'green_vertices_diff': {'added': [], 'removed': [2]},
     'red_vertices': [2],
     'red_vertices_diff': {'added': [2], 'removed': []},
     'sinks': [],
     'sinks_diff': {'added': [], 'removed': [1]},
     'sources': [3, 4],
     'sources_diff': {'added': [], 'removed': [5]},
     'urban_renewals': [],
     'urban_renewals_diff': {'added': [], 'removed': []}}}
>>> from sage.all import *
>>> B = [[Integer(0), Integer(4), Integer(0), -Integer(1)],[-Integer(4),Integer(0), Integer(3), Integer(0)],[Integer(0), -Integer(3), Integer(0), Integer(1)],[Integer(1), Integer(0), -Integer(1), Integer(0)]]
>>> S = ClusterSeed(matrix(B)); S.mutate([Integer(2),Integer(3),Integer(1),Integer(2),Integer(1),Integer(3),Integer(0),Integer(2)])
>>> S.mutation_analysis()
{0: {'d_matrix': [ 0  0  1  0]
                 [ 0 -1  0  0]
                 [ 0  0  0 -1]
                 [-1  0  0  0],
     'denominators': [1, 1, x0, 1],
     'edge_diff': 6,
     'edges': 13,
     'green_vertices': [0, 1, 3],
     'green_vertices_diff': {'added': [0], 'removed': []},
     'red_vertices': [2],
     'red_vertices_diff': {'added': [], 'removed': [0]},
     'sinks': [],
     'sinks_diff': {'added': [], 'removed': [2]},
     'sources': [],
     'sources_diff': {'added': [], 'removed': []},
     'urban_renewals': [],
     'urban_renewals_diff': {'added': [], 'removed': []}},
 1: {'d_matrix': [ 1  4  1  0]
                 [ 0  1  0  0]
                 [ 0  0  0 -1]
                 [ 1  4  0  0],
     'denominators': [x0*x3, x0^4*x1*x3^4, x0, 1],
     'edge_diff': 2,
     'edges': 9,
     'green_vertices': [0, 3],
     'green_vertices_diff': {'added': [0], 'removed': [1]},
     'red_vertices': [1, 2],
     'red_vertices_diff': {'added': [1], 'removed': [0]},
     'sinks': [2],
     'sinks_diff': {'added': [], 'removed': []},
     'sources': [],
     'sources_diff': {'added': [], 'removed': []},
     'urban_renewals': [],
     'urban_renewals_diff': {'added': [], 'removed': []}},
 2: {'d_matrix': [ 1  0  0  0]
                 [ 0 -1  0  0]
                 [ 0  0  0 -1]
                 [ 1  0  1  0],
     'denominators': [x0*x3, 1, x3, 1],
     'edge_diff': 0,
     'edges': 7,
     'green_vertices': [1, 2, 3],
     'green_vertices_diff': {'added': [2], 'removed': []},
     'red_vertices': [0],
     'red_vertices_diff': {'added': [], 'removed': [2]},
     'sinks': [],
     'sinks_diff': {'added': [], 'removed': [2]},
     'sources': [2],
     'sources_diff': {'added': [2], 'removed': []},
     'urban_renewals': [],
     'urban_renewals_diff': {'added': [], 'removed': []}},
 3: {'d_matrix': [ 1  0  1  1]
                 [ 0 -1  0  0]
                 [ 0  0  0  1]
                 [ 1  0  0  1],
     'denominators': [x0*x3, 1, x0, x0*x2*x3],
     'edge_diff': -1,
     'edges': 6,
     'green_vertices': [1],
     'green_vertices_diff': {'added': [], 'removed': [3]},
     'red_vertices': [0, 2, 3],
     'red_vertices_diff': {'added': [3], 'removed': []},
     'sinks': [2],
     'sinks_diff': {'added': [], 'removed': []},
     'sources': [1],
     'sources_diff': {'added': [1], 'removed': []},
     'urban_renewals': [],
     'urban_renewals_diff': {'added': [], 'removed': []}}}

>>> S = ClusterSeed(['A',Integer(3)]).principal_extension()
>>> S.mutation_analysis()
{0: {'d_matrix': [ 1  0  0]
                 [ 0 -1  0]
                 [ 0  0 -1],
     'denominators': [x0, 1, 1],
     'green_vertices': [1, 2],
     'green_vertices_diff': {'added': [], 'removed': [0]},
     'red_vertices': [0],
     'red_vertices_diff': {'added': [0], 'removed': []},
     'sinks': [],
     'sinks_diff': {'added': [], 'removed': [1]},
     'sources': [4, 5],
     'sources_diff': {'added': [], 'removed': [3]},
     'urban_renewals': [],
     'urban_renewals_diff': {'added': [], 'removed': []}},
 1: {'d_matrix': [-1  0  0]
                 [ 0  1  0]
                 [ 0  0 -1],
     'denominators': [1, x1, 1],
     'green_vertices': [0, 2],
     'green_vertices_diff': {'added': [], 'removed': [1]},
     'red_vertices': [1],
     'red_vertices_diff': {'added': [1], 'removed': []},
     'sinks': [0, 2, 4],
     'sinks_diff': {'added': [0, 2, 4], 'removed': [1]},
     'sources': [1, 3, 5],
     'sources_diff': {'added': [1], 'removed': [4]},
     'urban_renewals': [],
     'urban_renewals_diff': {'added': [], 'removed': []}},
 2: {'d_matrix': [-1  0  0]
                 [ 0 -1  0]
                 [ 0  0  1],
     'denominators': [1, 1, x2],
     'green_vertices': [0, 1],
     'green_vertices_diff': {'added': [], 'removed': [2]},
     'red_vertices': [2],
     'red_vertices_diff': {'added': [2], 'removed': []},
     'sinks': [],
     'sinks_diff': {'added': [], 'removed': [1]},
     'sources': [3, 4],
     'sources_diff': {'added': [], 'removed': [5]},
     'urban_renewals': [],
     'urban_renewals_diff': {'added': [], 'removed': []}}}
mutation_class(depth=+Infinity, show_depth=False, return_paths=False, up_to_equivalence=True, only_sink_source=False)[source]#

Return the mutation class of self with respect to certain constraints.

Note

Vertex labels are not tracked in this method.

INPUT:

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

  • show_depth – (default: False) if True, the actual depth of the mutation is shown

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

  • up_to_equivalence – (default: True) if True, only seeds up to equivalence are considered

  • sink_source – (default: False) if True, only mutations at sinks and sources are applied

EXAMPLES:

mutation_class_iter(depth=+Infinity, show_depth=False, return_paths=False, up_to_equivalence=True, only_sink_source=False)[source]#

Return an iterator for the mutation class of self with respect to certain constraints.

INPUT:

  • depth – (default: infinity) integer or infinity, only seeds with distance at most depth from self are returned.

  • show_depth – (default: False) if True, the current depth of the mutation is shown while computing.

  • return_paths – (default: False) if True, a shortest path of mutations from self to the given quiver is returned as well.

  • up_to_equivalence – (default: True) if True, only one seed up to simultaneous permutation of rows and columns of the exchange matrix is recorded.

  • sink_source – (default: False) if True, only mutations at sinks and sources are applied.

EXAMPLES:

A standard finite type example:

sage: S = ClusterSeed(['A',3])
sage: it = S.mutation_class_iter()
sage: for T in it: print(T)
A seed for a cluster algebra of rank 3 of type ['A', 3]
A seed for a cluster algebra of rank 3 of type ['A', 3]
A seed for a cluster algebra of rank 3 of type ['A', 3]
A seed for a cluster algebra of rank 3 of type ['A', 3]
A seed for a cluster algebra of rank 3 of type ['A', 3]
A seed for a cluster algebra of rank 3 of type ['A', 3]
A seed for a cluster algebra of rank 3 of type ['A', 3]
A seed for a cluster algebra of rank 3 of type ['A', 3]
A seed for a cluster algebra of rank 3 of type ['A', 3]
A seed for a cluster algebra of rank 3 of type ['A', 3]
A seed for a cluster algebra of rank 3 of type ['A', 3]
A seed for a cluster algebra of rank 3 of type ['A', 3]
A seed for a cluster algebra of rank 3 of type ['A', 3]
A seed for a cluster algebra of rank 3 of type ['A', 3]
>>> from sage.all import *
>>> S = ClusterSeed(['A',Integer(3)])
>>> it = S.mutation_class_iter()
>>> for T in it: print(T)
A seed for a cluster algebra of rank 3 of type ['A', 3]
A seed for a cluster algebra of rank 3 of type ['A', 3]
A seed for a cluster algebra of rank 3 of type ['A', 3]
A seed for a cluster algebra of rank 3 of type ['A', 3]
A seed for a cluster algebra of rank 3 of type ['A', 3]
A seed for a cluster algebra of rank 3 of type ['A', 3]
A seed for a cluster algebra of rank 3 of type ['A', 3]
A seed for a cluster algebra of rank 3 of type ['A', 3]
A seed for a cluster algebra of rank 3 of type ['A', 3]
A seed for a cluster algebra of rank 3 of type ['A', 3]
A seed for a cluster algebra of rank 3 of type ['A', 3]
A seed for a cluster algebra of rank 3 of type ['A', 3]
A seed for a cluster algebra of rank 3 of type ['A', 3]
A seed for a cluster algebra of rank 3 of type ['A', 3]

A finite type example with given depth:

sage: it = S.mutation_class_iter(depth=1)
sage: for T in it: print(T)
A seed for a cluster algebra of rank 3 of type ['A', 3]
A seed for a cluster algebra of rank 3 of type ['A', 3]
A seed for a cluster algebra of rank 3 of type ['A', 3]
A seed for a cluster algebra of rank 3 of type ['A', 3]
>>> from sage.all import *
>>> it = S.mutation_class_iter(depth=Integer(1))
>>> for T in it: print(T)
A seed for a cluster algebra of rank 3 of type ['A', 3]
A seed for a cluster algebra of rank 3 of type ['A', 3]
A seed for a cluster algebra of rank 3 of type ['A', 3]
A seed for a cluster algebra of rank 3 of type ['A', 3]

A finite type example where the depth is shown while computing:

sage: it = S.mutation_class_iter(show_depth=True)
sage: for T in it: pass
Depth: 0     found: 1          Time: ... s
Depth: 1     found: 4          Time: ... s
Depth: 2     found: 9          Time: ... s
Depth: 3     found: 13         Time: ... s
Depth: 4     found: 14         Time: ... s
>>> from sage.all import *
>>> it = S.mutation_class_iter(show_depth=True)
>>> for T in it: pass
Depth: 0     found: 1          Time: ... s
Depth: 1     found: 4          Time: ... s
Depth: 2     found: 9          Time: ... s
Depth: 3     found: 13         Time: ... s
Depth: 4     found: 14         Time: ... s

A finite type example with shortest paths returned:

sage: it = S.mutation_class_iter(return_paths=True)
sage: mutation_class = list(it)
sage: len(mutation_class)
14
sage: mutation_class[0]
(A seed for a cluster algebra of rank 3 of type ['A', 3], [])
>>> from sage.all import *
>>> it = S.mutation_class_iter(return_paths=True)
>>> mutation_class = list(it)
>>> len(mutation_class)
14
>>> mutation_class[Integer(0)]
(A seed for a cluster algebra of rank 3 of type ['A', 3], [])

Finite type examples not considered up to equivalence:

sage: it = S.mutation_class_iter(up_to_equivalence=False)
sage: len([T for T in it])
84

sage: it = ClusterSeed(['A',2]).mutation_class_iter(return_paths=True,
....:                                               up_to_equivalence=False)
sage: mutation_class = list(it)
sage: len(mutation_class)
10
sage: mutation_class[0]
(A seed for a cluster algebra of rank 2 of type ['A', 2], [])
>>> from sage.all import *
>>> it = S.mutation_class_iter(up_to_equivalence=False)
>>> len([T for T in it])
84

>>> it = ClusterSeed(['A',Integer(2)]).mutation_class_iter(return_paths=True,
...                                               up_to_equivalence=False)
>>> mutation_class = list(it)
>>> len(mutation_class)
10
>>> mutation_class[Integer(0)]
(A seed for a cluster algebra of rank 2 of type ['A', 2], [])

Check that Issue #14638 is fixed:

sage: S = ClusterSeed(['E',6])
sage: MC = S.mutation_class(depth=7); len(MC)  # long time
534
>>> from sage.all import *
>>> S = ClusterSeed(['E',Integer(6)])
>>> MC = S.mutation_class(depth=Integer(7)); len(MC)  # long time
534

Infinite type examples:

sage: S = ClusterSeed(['A',[1,1],1])
sage: it = S.mutation_class_iter()
sage: next(it)
A seed for a cluster algebra of rank 2 of type ['A', [1, 1], 1]
sage: next(it)
A seed for a cluster algebra of rank 2 of type ['A', [1, 1], 1]
sage: next(it)
A seed for a cluster algebra of rank 2 of type ['A', [1, 1], 1]
sage: next(it)
A seed for a cluster algebra of rank 2 of type ['A', [1, 1], 1]

sage: it = S.mutation_class_iter(depth=3, return_paths=True)
sage: for T in it: print(T)
(A seed for a cluster algebra of rank 2 of type ['A', [1, 1], 1], [])
(A seed for a cluster algebra of rank 2 of type ['A', [1, 1], 1], [1])
(A seed for a cluster algebra of rank 2 of type ['A', [1, 1], 1], [0])
(A seed for a cluster algebra of rank 2 of type ['A', [1, 1], 1], [1, 0])
(A seed for a cluster algebra of rank 2 of type ['A', [1, 1], 1], [0, 1])
(A seed for a cluster algebra of rank 2 of type ['A', [1, 1], 1], [1, 0, 1])
(A seed for a cluster algebra of rank 2 of type ['A', [1, 1], 1], [0, 1, 0])
>>> from sage.all import *
>>> S = ClusterSeed(['A',[Integer(1),Integer(1)],Integer(1)])
>>> it = S.mutation_class_iter()
>>> next(it)
A seed for a cluster algebra of rank 2 of type ['A', [1, 1], 1]
>>> next(it)
A seed for a cluster algebra of rank 2 of type ['A', [1, 1], 1]
>>> next(it)
A seed for a cluster algebra of rank 2 of type ['A', [1, 1], 1]
>>> next(it)
A seed for a cluster algebra of rank 2 of type ['A', [1, 1], 1]

>>> it = S.mutation_class_iter(depth=Integer(3), return_paths=True)
>>> for T in it: print(T)
(A seed for a cluster algebra of rank 2 of type ['A', [1, 1], 1], [])
(A seed for a cluster algebra of rank 2 of type ['A', [1, 1], 1], [1])
(A seed for a cluster algebra of rank 2 of type ['A', [1, 1], 1], [0])
(A seed for a cluster algebra of rank 2 of type ['A', [1, 1], 1], [1, 0])
(A seed for a cluster algebra of rank 2 of type ['A', [1, 1], 1], [0, 1])
(A seed for a cluster algebra of rank 2 of type ['A', [1, 1], 1], [1, 0, 1])
(A seed for a cluster algebra of rank 2 of type ['A', [1, 1], 1], [0, 1, 0])
mutation_sequence(sequence, show_sequence=False, fig_size=1.2, return_output='seed')[source]#

Return the seeds obtained by mutating self at all vertices in sequence.

INPUT:

  • sequence – an iterable of vertices of self.

  • show_sequence – (default: False) if True, a png containing the associated quivers is shown.

  • fig_size – (default: 1.2) factor by which the size of the plot is multiplied.

  • return_output – (default: 'seed') determines what output is to be returned:

    • if 'seed', outputs all the cluster seeds obtained by the sequence of mutations.

    • if 'matrix', outputs a list of exchange matrices.

    • if 'var', outputs a list of new cluster variables obtained at each step.

EXAMPLES:

sage: S = ClusterSeed(['A',2])
sage: for T in S.mutation_sequence([0,1,0]):
....:     print(T.b_matrix())
[ 0 -1]
[ 1  0]
[ 0  1]
[-1  0]
[ 0 -1]
[ 1  0]

sage: S = ClusterSeed(['A',2])
sage: S.mutation_sequence([0,1,0,1], return_output='var')
[(x1 + 1)/x0, (x0 + x1 + 1)/(x0*x1), (x0 + 1)/x1, x0]
>>> from sage.all import *
>>> S = ClusterSeed(['A',Integer(2)])
>>> for T in S.mutation_sequence([Integer(0),Integer(1),Integer(0)]):
...     print(T.b_matrix())
[ 0 -1]
[ 1  0]
[ 0  1]
[-1  0]
[ 0 -1]
[ 1  0]

>>> S = ClusterSeed(['A',Integer(2)])
>>> S.mutation_sequence([Integer(0),Integer(1),Integer(0),Integer(1)], return_output='var')
[(x1 + 1)/x0, (x0 + x1 + 1)/(x0*x1), (x0 + 1)/x1, x0]
mutation_type()[source]#

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.

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.

  • Might fail to work if it is used within different Sage processes simultaneously (that happened in the doctesting).

EXAMPLES:

  • finite types:

    sage: S = ClusterSeed(['A',5])
    sage: S._mutation_type = S._quiver._mutation_type = None
    sage: S.mutation_type()
    ['A', 5]
    
    sage: S = ClusterSeed([(0,1),(1,2),(2,3),(3,4)])
    sage: S.mutation_type()
    ['A', 5]
    
    sage: S = ClusterSeed(DiGraph([['a','b'],['c','b'],['c','d'],['e','d']]),
    ....:                 frozen=['c'])
    sage: S.mutation_type()
    [ ['A', 2], ['A', 2] ]
    
    >>> from sage.all import *
    >>> S = ClusterSeed(['A',Integer(5)])
    >>> S._mutation_type = S._quiver._mutation_type = None
    >>> S.mutation_type()
    ['A', 5]
    
    >>> S = ClusterSeed([(Integer(0),Integer(1)),(Integer(1),Integer(2)),(Integer(2),Integer(3)),(Integer(3),Integer(4))])
    >>> S.mutation_type()
    ['A', 5]
    
    >>> S = ClusterSeed(DiGraph([['a','b'],['c','b'],['c','d'],['e','d']]),
    ...                 frozen=['c'])
    >>> S.mutation_type()
    [ ['A', 2], ['A', 2] ]
    
  • affine types:

    sage: S = ClusterSeed(['E',8,[1,1]]); S
    A seed for a cluster algebra of rank 10 of type ['E', 8, [1, 1]]
    sage: S._mutation_type = S._quiver._mutation_type = None; S
    A seed for a cluster algebra of rank 10
    sage: S.mutation_type() # long time
    ['E', 8, [1, 1]]
    
    >>> from sage.all import *
    >>> S = ClusterSeed(['E',Integer(8),[Integer(1),Integer(1)]]); S
    A seed for a cluster algebra of rank 10 of type ['E', 8, [1, 1]]
    >>> S._mutation_type = S._quiver._mutation_type = None; S
    A seed for a cluster algebra of rank 10
    >>> S.mutation_type() # long time
    ['E', 8, [1, 1]]
    
  • the not yet working affine type D:

    sage: S = ClusterSeed(['D',4,1])
    sage: S._mutation_type = S._quiver._mutation_type = None
    sage: S.mutation_type() # todo: not implemented
    ['D', 4, 1]
    
    >>> from sage.all import *
    >>> S = ClusterSeed(['D',Integer(4),Integer(1)])
    >>> S._mutation_type = S._quiver._mutation_type = None
    >>> S.mutation_type() # todo: not implemented
    ['D', 4, 1]
    
  • the exceptional types:

    sage: S = ClusterSeed(['X',6])
    sage: S._mutation_type = S._quiver._mutation_type = None
    sage: S.mutation_type() # long time
    ['X', 6]
    
    >>> from sage.all import *
    >>> S = ClusterSeed(['X',Integer(6)])
    >>> S._mutation_type = S._quiver._mutation_type = None
    >>> S.mutation_type() # long time
    ['X', 6]
    
  • infinite types:

    sage: S = ClusterSeed(['GR',[4,9]])
    sage: S._mutation_type = S._quiver._mutation_type = None
    sage: S.mutation_type()
    'undetermined infinite mutation type'
    
    >>> from sage.all import *
    >>> S = ClusterSeed(['GR',[Integer(4),Integer(9)]])
    >>> S._mutation_type = S._quiver._mutation_type = None
    >>> S.mutation_type()
    'undetermined infinite mutation type'
    
mutations()[source]#

Return the list of mutations self has undergone if they are being tracked.

EXAMPLES:

sage: S = ClusterSeed(['A',3])
sage: S.mutations()
[]

sage: S.mutate([0,1,0,2])
sage: S.mutations()
[0, 1, 0, 2]

sage: S.track_mutations(False)
sage: S.mutations()
Traceback (most recent call last):
...
ValueError: Not recording mutation sequence.  Need to track mutations.
>>> from sage.all import *
>>> S = ClusterSeed(['A',Integer(3)])
>>> S.mutations()
[]

>>> S.mutate([Integer(0),Integer(1),Integer(0),Integer(2)])
>>> S.mutations()
[0, 1, 0, 2]

>>> S.track_mutations(False)
>>> S.mutations()
Traceback (most recent call last):
...
ValueError: Not recording mutation sequence.  Need to track mutations.
n()[source]#

Return the number of exchangeable variables of self.

EXAMPLES:

sage: S = ClusterSeed(['A', 3])
sage: S.n()
3
>>> from sage.all import *
>>> S = ClusterSeed(['A', Integer(3)])
>>> S.n()
3
oriented_exchange_graph()[source]#

Return the oriented exchange graph of self as a directed graph.

The seed must be a cluster seed for a cluster algebra of finite type with principal coefficients (the corresponding quiver must have mutable vertices \(0,1,...,n-1\)).

EXAMPLES:

sage: S = ClusterSeed(['A', 2]).principal_extension()
sage: G = S.oriented_exchange_graph(); G
Digraph on 5 vertices
sage: G.out_degree_sequence()
[2, 1, 1, 1, 0]

sage: S = ClusterSeed(['B', 2]).principal_extension()
sage: G = S.oriented_exchange_graph(); G
Digraph on 6 vertices
sage: G.out_degree_sequence()
[2, 1, 1, 1, 1, 0]
>>> from sage.all import *
>>> S = ClusterSeed(['A', Integer(2)]).principal_extension()
>>> G = S.oriented_exchange_graph(); G
Digraph on 5 vertices
>>> G.out_degree_sequence()
[2, 1, 1, 1, 0]

>>> S = ClusterSeed(['B', Integer(2)]).principal_extension()
>>> G = S.oriented_exchange_graph(); G
Digraph on 6 vertices
>>> G.out_degree_sequence()
[2, 1, 1, 1, 1, 0]
plot(circular=False, mark=None, save_pos=False, force_c=False, with_greens=False, add_labels=False)[source]#

Return the plot of the quiver of self.

INPUT:

  • circular – (default: False) if True, the circular plot is chosen, otherwise >>spring<< is used.

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

  • save_pos – (default: False) if True, the positions of the vertices are saved.

  • force_c – (default: False) if True, will show the frozen vertices even if they were never initialized

  • with_greens – (default: False) if True, will display the green vertices in green

  • add_labels – (default: False) if True, will use the initial variables as labels

EXAMPLES:

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

Return the principal extension of self, yielding a \(2n \times n\) matrix.

Raises an error if the input seed has a non-square exchange matrix. In this case, the method instead adds \(n\) frozen variables to any previously frozen variables. I.e., the seed obtained by adding a frozen variable to every exchangeable variable of self.

EXAMPLES:

sage: S = ClusterSeed([[0,1],[1,2],[2,3],[2,4]]); S
A seed for a cluster algebra of rank 5

sage: T = S.principal_extension(); T
A seed for a cluster algebra of rank 5 with principal coefficients

sage: T.b_matrix()
[ 0  1  0  0  0]
[-1  0  1  0  0]
[ 0 -1  0  1  1]
[ 0  0 -1  0  0]
[ 0  0 -1  0  0]
[ 1  0  0  0  0]
[ 0  1  0  0  0]
[ 0  0  1  0  0]
[ 0  0  0  1  0]
[ 0  0  0  0  1]

sage: S = ClusterSeed(['A', 4], user_labels=['a', 'b', 'c', 'd'])
sage: T = S.principal_extension()
sage: T.cluster()
[a, b, c, d]
sage: T.coefficients()
[y0, y1, y2, y3]
sage: S2 = ClusterSeed(['A', 4], user_labels={0:'a', 1:'b', 2:'c', 3:'d'})
sage: S2 == S
True
sage: T2 = S2.principal_extension()
sage: T2 == T
True
>>> from sage.all import *
>>> S = ClusterSeed([[Integer(0),Integer(1)],[Integer(1),Integer(2)],[Integer(2),Integer(3)],[Integer(2),Integer(4)]]); S
A seed for a cluster algebra of rank 5

>>> T = S.principal_extension(); T
A seed for a cluster algebra of rank 5 with principal coefficients

>>> T.b_matrix()
[ 0  1  0  0  0]
[-1  0  1  0  0]
[ 0 -1  0  1  1]
[ 0  0 -1  0  0]
[ 0  0 -1  0  0]
[ 1  0  0  0  0]
[ 0  1  0  0  0]
[ 0  0  1  0  0]
[ 0  0  0  1  0]
[ 0  0  0  0  1]

>>> S = ClusterSeed(['A', Integer(4)], user_labels=['a', 'b', 'c', 'd'])
>>> T = S.principal_extension()
>>> T.cluster()
[a, b, c, d]
>>> T.coefficients()
[y0, y1, y2, y3]
>>> S2 = ClusterSeed(['A', Integer(4)], user_labels={Integer(0):'a', Integer(1):'b', Integer(2):'c', Integer(3):'d'})
>>> S2 == S
True
>>> T2 = S2.principal_extension()
>>> T2 == T
True
quiver()[source]#

Return the quiver associated to self.

EXAMPLES:

sage: S = ClusterSeed(['A',3])
sage: S.quiver()
Quiver on 3 vertices of type ['A', 3]
>>> from sage.all import *
>>> S = ClusterSeed(['A',Integer(3)])
>>> S.quiver()
Quiver on 3 vertices of type ['A', 3]
red_vertices()[source]#

Return the list of red vertices of self.

A vertex is defined to be red if its c-vector has all non-negative entries. More information on red vertices can be found at [BDP2013].

OUTPUT:

The red vertices as a list of integers.

EXAMPLES:

sage: ClusterSeed(['A',3]).principal_extension().red_vertices()
[]

sage: ClusterSeed(['A',[3,3],1]).principal_extension().red_vertices()
[]

sage: Q = ClusterSeed(['A',[3,3],1]).principal_extension()
sage: Q.mutate(1)
sage: Q.red_vertices()
[1]
>>> from sage.all import *
>>> ClusterSeed(['A',Integer(3)]).principal_extension().red_vertices()
[]

>>> ClusterSeed(['A',[Integer(3),Integer(3)],Integer(1)]).principal_extension().red_vertices()
[]

>>> Q = ClusterSeed(['A',[Integer(3),Integer(3)],Integer(1)]).principal_extension()
>>> Q.mutate(Integer(1))
>>> Q.red_vertices()
[1]
reorient(data)[source]#

Reorients self with respect to the given total order, or with respect to an iterator of ordered pairs.

Warning

  • This operation might change the mutation type of self.

  • Ignores ordered pairs \((i,j)\) for which neither \((i,j)\) nor \((j,i)\) is an edge of self.

INPUT:

  • data – an iterator defining a total order on self.vertices(), or an iterator of ordered pairs in self defining the new orientation of these edges.

EXAMPLES:

sage: S = ClusterSeed(['A',[2,3],1])
sage: S.mutation_type()
['A', [2, 3], 1]

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

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

sage: S.reorient([0,1,2,3,4])
sage: S.mutation_type()
['A', [1, 4], 1]
>>> from sage.all import *
>>> S = ClusterSeed(['A',[Integer(2),Integer(3)],Integer(1)])
>>> S.mutation_type()
['A', [2, 3], 1]

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

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

>>> S.reorient([Integer(0),Integer(1),Integer(2),Integer(3),Integer(4)])
>>> S.mutation_type()
['A', [1, 4], 1]
reset_cluster()[source]#

Reset the cluster of self to the initial cluster.

EXAMPLES:

sage: S = ClusterSeed(['A',3])
sage: S.mutate([1,2,1])
sage: S.cluster()
[x0, (x1 + 1)/x2, (x0*x2 + x1 + 1)/(x1*x2)]

sage: S.reset_cluster()
sage: S.cluster()
[x0, x1, x2]

sage: T = S.principal_extension()
sage: T.cluster()
[x0, x1, x2]
sage: T.mutate([1,2,1])
sage: T.cluster()
[x0, (x1*y2 + x0)/x2, (x1*y1*y2 + x0*y1 + x2)/(x1*x2)]

sage: T.reset_cluster()
sage: T.cluster()
[x0, x1, x2]

sage: S = ClusterSeed(['B',3], user_labels=[[1,2],[2,3],[3,4]],
....:                 user_labels_prefix='p')
sage: S.mutate([0,1])
sage: S.cluster()
[(p_2_3 + 1)/p_1_2, (p_1_2*p_3_4^2 + p_2_3 + 1)/(p_1_2*p_2_3), p_3_4]

sage: S.reset_cluster()
sage: S.cluster()
[p_1_2, p_2_3, p_3_4]
sage: S.g_matrix()
[1 0 0]
[0 1 0]
[0 0 1]
sage: S.f_polynomials()
[1, 1, 1]
>>> from sage.all import *
>>> S = ClusterSeed(['A',Integer(3)])
>>> S.mutate([Integer(1),Integer(2),Integer(1)])
>>> S.cluster()
[x0, (x1 + 1)/x2, (x0*x2 + x1 + 1)/(x1*x2)]

>>> S.reset_cluster()
>>> S.cluster()
[x0, x1, x2]

>>> T = S.principal_extension()
>>> T.cluster()
[x0, x1, x2]
>>> T.mutate([Integer(1),Integer(2),Integer(1)])
>>> T.cluster()
[x0, (x1*y2 + x0)/x2, (x1*y1*y2 + x0*y1 + x2)/(x1*x2)]

>>> T.reset_cluster()
>>> T.cluster()
[x0, x1, x2]

>>> S = ClusterSeed(['B',Integer(3)], user_labels=[[Integer(1),Integer(2)],[Integer(2),Integer(3)],[Integer(3),Integer(4)]],
...                 user_labels_prefix='p')
>>> S.mutate([Integer(0),Integer(1)])
>>> S.cluster()
[(p_2_3 + 1)/p_1_2, (p_1_2*p_3_4^2 + p_2_3 + 1)/(p_1_2*p_2_3), p_3_4]

>>> S.reset_cluster()
>>> S.cluster()
[p_1_2, p_2_3, p_3_4]
>>> S.g_matrix()
[1 0 0]
[0 1 0]
[0 0 1]
>>> S.f_polynomials()
[1, 1, 1]
reset_coefficients()[source]#

Reset the coefficients of self to the frozen variables but keep the current cluster.

This raises an error if the number of frozen variables is different from the number of exchangeable variables.

Warning

This command to be phased out since use_c_vectors() does this more effectively.

EXAMPLES:

sage: S = ClusterSeed(['A',3]).principal_extension()
sage: S.b_matrix()
[ 0  1  0]
[-1  0 -1]
[ 0  1  0]
[ 1  0  0]
[ 0  1  0]
[ 0  0  1]
sage: S.mutate([1,2,1])
sage: S.b_matrix()
[ 0  1 -1]
[-1  0  1]
[ 1 -1  0]
[ 1  0  0]
[ 0  1 -1]
[ 0  0 -1]
sage: S.reset_coefficients()
sage: S.b_matrix()
[ 0  1 -1]
[-1  0  1]
[ 1 -1  0]
[ 1  0  0]
[ 0  1  0]
[ 0  0  1]
>>> from sage.all import *
>>> S = ClusterSeed(['A',Integer(3)]).principal_extension()
>>> S.b_matrix()
[ 0  1  0]
[-1  0 -1]
[ 0  1  0]
[ 1  0  0]
[ 0  1  0]
[ 0  0  1]
>>> S.mutate([Integer(1),Integer(2),Integer(1)])
>>> S.b_matrix()
[ 0  1 -1]
[-1  0  1]
[ 1 -1  0]
[ 1  0  0]
[ 0  1 -1]
[ 0  0 -1]
>>> S.reset_coefficients()
>>> S.b_matrix()
[ 0  1 -1]
[-1  0  1]
[ 1 -1  0]
[ 1  0  0]
[ 0  1  0]
[ 0  0  1]
save_image(filename, circular=False, mark=None, save_pos=False)[source]#

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

INPUT:

  • filename – the filename the image is saved to.

  • circular – (default: False) if True, the circular plot is chosen, otherwise >>spring<< is used.

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

  • save_pos – (default: False) if True, the positions of the vertices are saved.

EXAMPLES:

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

Will force set the c-matrix according to a matrix, a quiver, or a seed.

INPUT:

  • data – The matrix to set the c-matrix to. Also allowed to be a quiver or cluster seed, in which case the b-matrix is used.

EXAMPLES:

sage: S = ClusterSeed(['A',3])
sage: X = matrix([[0,0,1],[0,1,0],[1,0,0]])
sage: S.set_c_matrix(X)
sage: S.c_matrix()
[0 0 1]
[0 1 0]
[1 0 0]

sage: Y = matrix([[-1,0,1],[0,1,0],[1,0,0]])
sage: S.set_c_matrix(Y)
C matrix does not look to be valid - there exists a column
containing positive and negative entries.
Continuing...

sage: Z = matrix([[1,0,1],[0,1,0],[2,0,2]])
sage: S.set_c_matrix(Z)
C matrix does not look to be valid - not a linearly independent set.
Continuing...
>>> from sage.all import *
>>> S = ClusterSeed(['A',Integer(3)])
>>> X = matrix([[Integer(0),Integer(0),Integer(1)],[Integer(0),Integer(1),Integer(0)],[Integer(1),Integer(0),Integer(0)]])
>>> S.set_c_matrix(X)
>>> S.c_matrix()
[0 0 1]
[0 1 0]
[1 0 0]

>>> Y = matrix([[-Integer(1),Integer(0),Integer(1)],[Integer(0),Integer(1),Integer(0)],[Integer(1),Integer(0),Integer(0)]])
>>> S.set_c_matrix(Y)
C matrix does not look to be valid - there exists a column
containing positive and negative entries.
Continuing...

>>> Z = matrix([[Integer(1),Integer(0),Integer(1)],[Integer(0),Integer(1),Integer(0)],[Integer(2),Integer(0),Integer(2)]])
>>> S.set_c_matrix(Z)
C matrix does not look to be valid - not a linearly independent set.
Continuing...
set_cluster(cluster, force=False)[source]#

Sets the cluster for self to cluster.

Warning

Initialization may lead to inconsistent data.

INPUT:

  • cluster – an iterable defining a cluster for self.

EXAMPLES:

sage: S = ClusterSeed(['A',3])
sage: cluster = S.cluster()
sage: S.mutate([1,2,1])
sage: S.cluster()
[x0, (x1 + 1)/x2, (x0*x2 + x1 + 1)/(x1*x2)]
sage: cluster2 = S.cluster()

sage: S.set_cluster(cluster)
Warning: using set_cluster at this point could lead to inconsistent seed data.

sage: S.set_cluster(cluster, force=True)
sage: S.cluster()
[x0, x1, x2]
sage: S.set_cluster(cluster2, force=True)
sage: S.cluster()
[x0, (x1 + 1)/x2, (x0*x2 + x1 + 1)/(x1*x2)]

sage: S = ClusterSeed(['A',3]); S.use_fpolys(False)
sage: S.set_cluster([1,1,1])
Warning: clusters not being tracked so this command is ignored.
>>> from sage.all import *
>>> S = ClusterSeed(['A',Integer(3)])
>>> cluster = S.cluster()
>>> S.mutate([Integer(1),Integer(2),Integer(1)])
>>> S.cluster()
[x0, (x1 + 1)/x2, (x0*x2 + x1 + 1)/(x1*x2)]
>>> cluster2 = S.cluster()

>>> S.set_cluster(cluster)
Warning: using set_cluster at this point could lead to inconsistent seed data.

>>> S.set_cluster(cluster, force=True)
>>> S.cluster()
[x0, x1, x2]
>>> S.set_cluster(cluster2, force=True)
>>> S.cluster()
[x0, (x1 + 1)/x2, (x0*x2 + x1 + 1)/(x1*x2)]

>>> S = ClusterSeed(['A',Integer(3)]); S.use_fpolys(False)
>>> S.set_cluster([Integer(1),Integer(1),Integer(1)])
Warning: clusters not being tracked so this command is ignored.
show(fig_size=1, circular=False, mark=None, save_pos=False, force_c=False, with_greens=False, add_labels=False)[source]#

Shows the plot of the quiver of self.

INPUT:

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

  • circular – (default: False) if True, the circular plot is chosen, otherwise >>spring<< is used.

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

  • save_pos – (default: False) if True, the positions of the vertices are saved.

  • force_c – (default: False) if True, will show the frozen vertices even if they were never initialized

  • with_greens – (default: False) if True, will display the green vertices in green

  • add_labels – (default: False) if True, will use the initial variables as labels

smallest_c_vector()[source]#

Return the vertex with the smallest c-vector.

OUTPUT: An integer.

EXAMPLES:

sage: B = matrix([[0,2], [-2,0]])
sage: C = ClusterSeed(B).principal_extension()
sage: C.mutate(0)
sage: C.smallest_c_vector()
0
>>> from sage.all import *
>>> B = matrix([[Integer(0),Integer(2)], [-Integer(2),Integer(0)]])
>>> C = ClusterSeed(B).principal_extension()
>>> C.mutate(Integer(0))
>>> C.smallest_c_vector()
0
track_mutations(use=True)[source]#

Begin tracking the mutation path.

Warning

May initialize all other data to ensure that all c-, d-, and g-vectors agree on the start of mutations.

INPUT:

  • use – (default: True) If True, will begin filling the mutation path

EXAMPLES:

sage: S = ClusterSeed(['A',4]); S.track_mutations(False)
sage: S.mutate(0)
sage: S.mutations()
Traceback (most recent call last):
...
ValueError: Not recording mutation sequence.  Need to track mutations.
sage: S.track_mutations(True)
sage: S.g_matrix()
[1 0 0 0]
[0 1 0 0]
[0 0 1 0]
[0 0 0 1]

sage: S.mutate([0,1])
sage: S.mutations()
[0, 1]
>>> from sage.all import *
>>> S = ClusterSeed(['A',Integer(4)]); S.track_mutations(False)
>>> S.mutate(Integer(0))
>>> S.mutations()
Traceback (most recent call last):
...
ValueError: Not recording mutation sequence.  Need to track mutations.
>>> S.track_mutations(True)
>>> S.g_matrix()
[1 0 0 0]
[0 1 0 0]
[0 0 1 0]
[0 0 0 1]

>>> S.mutate([Integer(0),Integer(1)])
>>> S.mutations()
[0, 1]
universal_extension()[source]#

Return the universal extension of self.

This is the initial seed of the associated cluster algebra with universal coefficients, as defined in section 12 of [FZ2007].

This method works only if self is a bipartite, finite-type seed.

Due to some limitations in the current implementation of CartanType, we need to construct the set of almost positive coroots by hand. As a consequence their ordering is not the standard one (the rows of the bottom part of the exchange matrix might be a shuffling of those you would expect).

EXAMPLES:

sage: S = ClusterSeed(['A',2])
sage: T = S.universal_extension()
sage: T.b_matrix()
[ 0  1]
[-1  0]
[-1  0]
[ 1  0]
[ 1 -1]
[ 0  1]
[ 0 -1]

sage: S = ClusterSeed(['A',3])
sage: T = S.universal_extension()
sage: T.b_matrix()
[ 0  1  0]
[-1  0 -1]
[ 0  1  0]
[-1  0  0]
[ 1  0  0]
[ 1 -1  0]
[ 1 -1  1]
[ 0  1  0]
[ 0 -1  0]
[ 0 -1  1]
[ 0  0 -1]
[ 0  0  1]

sage: S = ClusterSeed(['B',2])
sage: T = S.universal_extension()
sage: T.b_matrix()
[ 0  1]
[-2  0]
[-1  0]
[ 1  0]
[ 1 -1]
[ 2 -1]
[ 0  1]
[ 0 -1]

sage: S = ClusterSeed(['A', 5], user_labels=[-2, -1, 0, 1 ,2])
sage: U = S.universal_extension()
sage: U.b_matrix() == ClusterSeed(['A', 5]).universal_extension().b_matrix()
True
>>> from sage.all import *
>>> S = ClusterSeed(['A',Integer(2)])
>>> T = S.universal_extension()
>>> T.b_matrix()
[ 0  1]
[-1  0]
[-1  0]
[ 1  0]
[ 1 -1]
[ 0  1]
[ 0 -1]

>>> S = ClusterSeed(['A',Integer(3)])
>>> T = S.universal_extension()
>>> T.b_matrix()
[ 0  1  0]
[-1  0 -1]
[ 0  1  0]
[-1  0  0]
[ 1  0  0]
[ 1 -1  0]
[ 1 -1  1]
[ 0  1  0]
[ 0 -1  0]
[ 0 -1  1]
[ 0  0 -1]
[ 0  0  1]

>>> S = ClusterSeed(['B',Integer(2)])
>>> T = S.universal_extension()
>>> T.b_matrix()
[ 0  1]
[-2  0]
[-1  0]
[ 1  0]
[ 1 -1]
[ 2 -1]
[ 0  1]
[ 0 -1]

>>> S = ClusterSeed(['A', Integer(5)], user_labels=[-Integer(2), -Integer(1), Integer(0), Integer(1) ,Integer(2)])
>>> U = S.universal_extension()
>>> U.b_matrix() == ClusterSeed(['A', Integer(5)]).universal_extension().b_matrix()
True
urban_renewals(return_first=False)[source]#

Return the list of the urban renewal vertices of self.

An urban renewal vertex is one in which there are two arrows pointing toward the vertex and two arrows pointing away.

INPUT:

  • return_first – (default: False) if True, will return the first urban renewal

OUTPUT:

A list of vertices (as integers)

EXAMPLES:

sage: G = ClusterSeed(['GR',[4,9]]); G.urban_renewals()
[5, 6]
>>> from sage.all import *
>>> G = ClusterSeed(['GR',[Integer(4),Integer(9)]]); G.urban_renewals()
[5, 6]
use_c_vectors(use=True, bot_is_c=False, force=False)[source]#

Reconstruct c-vectors from other data or initialize if no usable data exists.

Warning: Initialization may lead to inconsistent data.

INPUT:

  • use – (default: True) If True, will use c-vectors

  • bot_is_c – (default: False) If True and ClusterSeed self has self._m == self._n, then will assume bottom half of the extended exchange matrix is the c-matrix. If True, lets the ClusterSeed know c-vectors can be calculated.

EXAMPLES:

sage: S = ClusterSeed(['A',4])
sage: S.use_c_vectors(False); S.use_g_vectors(False)
sage: S.use_fpolys(False); S.track_mutations(False)
sage: S.use_c_vectors(True)
Warning: Initializing c-vectors at this point
could lead to inconsistent seed data.

sage: S.use_c_vectors(True, force=True)
sage: S.c_matrix()
[1 0 0 0]
[0 1 0 0]
[0 0 1 0]
[0 0 0 1]

sage: S = ClusterSeed(['A',4])
sage: S.use_c_vectors(False); S.use_g_vectors(False)
sage: S.use_fpolys(False); S.track_mutations(False)
sage: S.mutate(1)
sage: S.use_c_vectors(True, force=True)
sage: S.c_matrix()
[1 0 0 0]
[0 1 0 0]
[0 0 1 0]
[0 0 0 1]
>>> from sage.all import *
>>> S = ClusterSeed(['A',Integer(4)])
>>> S.use_c_vectors(False); S.use_g_vectors(False)
>>> S.use_fpolys(False); S.track_mutations(False)
>>> S.use_c_vectors(True)
Warning: Initializing c-vectors at this point
could lead to inconsistent seed data.

>>> S.use_c_vectors(True, force=True)
>>> S.c_matrix()
[1 0 0 0]
[0 1 0 0]
[0 0 1 0]
[0 0 0 1]

>>> S = ClusterSeed(['A',Integer(4)])
>>> S.use_c_vectors(False); S.use_g_vectors(False)
>>> S.use_fpolys(False); S.track_mutations(False)
>>> S.mutate(Integer(1))
>>> S.use_c_vectors(True, force=True)
>>> S.c_matrix()
[1 0 0 0]
[0 1 0 0]
[0 0 1 0]
[0 0 0 1]
use_d_vectors(use=True, force=False)[source]#

Reconstruct d-vectors from other data or initialize if no usable data exists.

Warning

Initialization may lead to inconsistent data.

INPUT:

  • use – (default: True) If True, will use d-vectors

EXAMPLES:

sage: S = ClusterSeed(['A',4])
sage: S.use_d_vectors(True)
sage: S.d_matrix()
[-1  0  0  0]
[ 0 -1  0  0]
[ 0  0 -1  0]
[ 0  0  0 -1]

sage: S = ClusterSeed(['A',4]); S.use_d_vectors(False)
sage: S.track_mutations(False); S.mutate(1); S.d_matrix()
[-1  0  0  0]
[ 0  1  0  0]
[ 0  0 -1  0]
[ 0  0  0 -1]
sage: S.use_fpolys(False)
sage: S.d_matrix()
Traceback (most recent call last):
...
ValueError: Unable to calculate d-vectors. Need to use d vectors.

sage: S = ClusterSeed(['A',4]); S.use_d_vectors(False)
sage: S.track_mutations(False); S.mutate(1); S.d_matrix()
[-1  0  0  0]
[ 0  1  0  0]
[ 0  0 -1  0]
[ 0  0  0 -1]
sage: S.use_fpolys(False)
sage: S.use_d_vectors(True)
Warning: Initializing d-vectors at this point
could lead to inconsistent seed data.

sage: S.use_d_vectors(True, force=True)
sage: S.d_matrix()
[-1  0  0  0]
[ 0 -1  0  0]
[ 0  0 -1  0]
[ 0  0  0 -1]

sage: S = ClusterSeed(['A',4]); S.mutate(1); S.d_matrix()
[-1  0  0  0]
[ 0  1  0  0]
[ 0  0 -1  0]
[ 0  0  0 -1]
sage: S = ClusterSeed(['A',4])
sage: S.use_d_vectors(True); S.mutate(1); S.d_matrix()
[-1  0  0  0]
[ 0  1  0  0]
[ 0  0 -1  0]
[ 0  0  0 -1]
>>> from sage.all import *
>>> S = ClusterSeed(['A',Integer(4)])
>>> S.use_d_vectors(True)
>>> S.d_matrix()
[-1  0  0  0]
[ 0 -1  0  0]
[ 0  0 -1  0]
[ 0  0  0 -1]

>>> S = ClusterSeed(['A',Integer(4)]); S.use_d_vectors(False)
>>> S.track_mutations(False); S.mutate(Integer(1)); S.d_matrix()
[-1  0  0  0]
[ 0  1  0  0]
[ 0  0 -1  0]
[ 0  0  0 -1]
>>> S.use_fpolys(False)
>>> S.d_matrix()
Traceback (most recent call last):
...
ValueError: Unable to calculate d-vectors. Need to use d vectors.

>>> S = ClusterSeed(['A',Integer(4)]); S.use_d_vectors(False)
>>> S.track_mutations(False); S.mutate(Integer(1)); S.d_matrix()
[-1  0  0  0]
[ 0  1  0  0]
[ 0  0 -1  0]
[ 0  0  0 -1]
>>> S.use_fpolys(False)
>>> S.use_d_vectors(True)
Warning: Initializing d-vectors at this point
could lead to inconsistent seed data.

>>> S.use_d_vectors(True, force=True)
>>> S.d_matrix()
[-1  0  0  0]
[ 0 -1  0  0]
[ 0  0 -1  0]
[ 0  0  0 -1]

>>> S = ClusterSeed(['A',Integer(4)]); S.mutate(Integer(1)); S.d_matrix()
[-1  0  0  0]
[ 0  1  0  0]
[ 0  0 -1  0]
[ 0  0  0 -1]
>>> S = ClusterSeed(['A',Integer(4)])
>>> S.use_d_vectors(True); S.mutate(Integer(1)); S.d_matrix()
[-1  0  0  0]
[ 0  1  0  0]
[ 0  0 -1  0]
[ 0  0  0 -1]
use_fpolys(use=True, user_labels=None, user_labels_prefix=None)[source]#

Use F-polynomials in our Cluster Seed

Note: This will automatically try to recompute the cluster variables if possible

INPUT:

  • use – (default: True) If True, will use F-polynomials

  • user_labels – (default: None) If set, will overwrite the default cluster variable labels

  • user_labels_prefix – (default: None) If set, will overwrite the default

EXAMPLES:

sage: S = ClusterSeed(['A',4]); S.use_fpolys(False); S._cluster
sage: S.use_fpolys(True)
sage: S.cluster()
[x0, x1, x2, x3]

sage: S = ClusterSeed(['A',4]); S.use_fpolys(False); S.track_mutations(False)
sage: S.mutate(1)
sage: S.use_fpolys(True)
Traceback (most recent call last):
...
ValueError: F-polynomials and Cluster Variables cannot be reconstructed
from given data.
sage: S.cluster()
Traceback (most recent call last):
...
ValueError: Clusters not being tracked
>>> from sage.all import *
>>> S = ClusterSeed(['A',Integer(4)]); S.use_fpolys(False); S._cluster
>>> S.use_fpolys(True)
>>> S.cluster()
[x0, x1, x2, x3]

>>> S = ClusterSeed(['A',Integer(4)]); S.use_fpolys(False); S.track_mutations(False)
>>> S.mutate(Integer(1))
>>> S.use_fpolys(True)
Traceback (most recent call last):
...
ValueError: F-polynomials and Cluster Variables cannot be reconstructed
from given data.
>>> S.cluster()
Traceback (most recent call last):
...
ValueError: Clusters not being tracked
use_g_vectors(use=True, force=False)[source]#

Reconstruct g-vectors from other data or initialize if no usable data exists.

Warning

Initialization may lead to inconsistent data.

INPUT:

  • use – (default: True) If True, will use g-vectors

EXAMPLES:

sage: S = ClusterSeed(['A',4])
sage: S.use_g_vectors(False); S.use_fpolys(False)
sage: S.use_g_vectors(True)
sage: S.g_matrix()
[1 0 0 0]
[0 1 0 0]
[0 0 1 0]
[0 0 0 1]

sage: S = ClusterSeed(['A',4])
sage: S.use_g_vectors(False); S.use_fpolys(False)
sage: S.mutate(1)
sage: S.use_g_vectors(True)
sage: S.g_matrix()
[ 1  0  0  0]
[ 0 -1  0  0]
[ 0  0  1  0]
[ 0  0  0  1]

sage: S = ClusterSeed(['A',4])
sage: S.use_g_vectors(False); S.use_fpolys(False); S.track_mutations(False)
sage: S.mutate(1)
sage: S.use_c_vectors(False)
sage: S.g_matrix()
Traceback (most recent call last):
...
ValueError: Unable to calculate g-vectors. Need to use g vectors.

sage: S = ClusterSeed(['A',4])
sage: S.use_g_vectors(False); S.use_fpolys(False); S.track_mutations(False)
sage: S.mutate(1)
sage: S.use_c_vectors(False)
sage: S.use_g_vectors(True)
Warning: Initializing g-vectors at this point
could lead to inconsistent seed data.

sage: S.use_g_vectors(True, force=True)
sage: S.g_matrix()
[1 0 0 0]
[0 1 0 0]
[0 0 1 0]
[0 0 0 1]
>>> from sage.all import *
>>> S = ClusterSeed(['A',Integer(4)])
>>> S.use_g_vectors(False); S.use_fpolys(False)
>>> S.use_g_vectors(True)
>>> S.g_matrix()
[1 0 0 0]
[0 1 0 0]
[0 0 1 0]
[0 0 0 1]

>>> S = ClusterSeed(['A',Integer(4)])
>>> S.use_g_vectors(False); S.use_fpolys(False)
>>> S.mutate(Integer(1))
>>> S.use_g_vectors(True)
>>> S.g_matrix()
[ 1  0  0  0]
[ 0 -1  0  0]
[ 0  0  1  0]
[ 0  0  0  1]

>>> S = ClusterSeed(['A',Integer(4)])
>>> S.use_g_vectors(False); S.use_fpolys(False); S.track_mutations(False)
>>> S.mutate(Integer(1))
>>> S.use_c_vectors(False)
>>> S.g_matrix()
Traceback (most recent call last):
...
ValueError: Unable to calculate g-vectors. Need to use g vectors.

>>> S = ClusterSeed(['A',Integer(4)])
>>> S.use_g_vectors(False); S.use_fpolys(False); S.track_mutations(False)
>>> S.mutate(Integer(1))
>>> S.use_c_vectors(False)
>>> S.use_g_vectors(True)
Warning: Initializing g-vectors at this point
could lead to inconsistent seed data.

>>> S.use_g_vectors(True, force=True)
>>> S.g_matrix()
[1 0 0 0]
[0 1 0 0]
[0 0 1 0]
[0 0 0 1]
variable_class(depth=+Infinity, ignore_bipartite_belt=False)[source]#

Return all cluster variables in the mutation class of self.

INPUT:

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

  • ignore_bipartite_belt – (default: False) if True, the algorithm does not use the bipartite belt

EXAMPLES:

variable_class_iter(depth=+Infinity, ignore_bipartite_belt=False)[source]#

Return an iterator for all cluster variables in the mutation class of self.

INPUT:

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

  • ignore_bipartite_belt – (default: False) if True, the algorithm does not use the bipartite belt

EXAMPLES:

A standard finite type example:

sage: S = ClusterSeed(['A',3])
sage: it = S.variable_class_iter()
sage: for T in it: print(T)
x0
x1
x2
(x1 + 1)/x0
(x1^2 + x0*x2 + 2*x1 + 1)/(x0*x1*x2)
(x1 + 1)/x2
(x0*x2 + x1 + 1)/(x0*x1)
(x0*x2 + 1)/x1
(x0*x2 + x1 + 1)/(x1*x2)
>>> from sage.all import *
>>> S = ClusterSeed(['A',Integer(3)])
>>> it = S.variable_class_iter()
>>> for T in it: print(T)
x0
x1
x2
(x1 + 1)/x0
(x1^2 + x0*x2 + 2*x1 + 1)/(x0*x1*x2)
(x1 + 1)/x2
(x0*x2 + x1 + 1)/(x0*x1)
(x0*x2 + 1)/x1
(x0*x2 + x1 + 1)/(x1*x2)

Finite type examples with given depth:

sage: it = S.variable_class_iter(depth=1)
sage: for T in it: print(T)
Found a bipartite seed - restarting the depth counter at zero
and constructing the variable class using its bipartite belt.
x0
x1
x2
(x1 + 1)/x0
(x1^2 + x0*x2 + 2*x1 + 1)/(x0*x1*x2)
(x1 + 1)/x2
(x0*x2 + x1 + 1)/(x0*x1)
(x0*x2 + 1)/x1
(x0*x2 + x1 + 1)/(x1*x2)
>>> from sage.all import *
>>> it = S.variable_class_iter(depth=Integer(1))
>>> for T in it: print(T)
Found a bipartite seed - restarting the depth counter at zero
and constructing the variable class using its bipartite belt.
x0
x1
x2
(x1 + 1)/x0
(x1^2 + x0*x2 + 2*x1 + 1)/(x0*x1*x2)
(x1 + 1)/x2
(x0*x2 + x1 + 1)/(x0*x1)
(x0*x2 + 1)/x1
(x0*x2 + x1 + 1)/(x1*x2)

Note that the notion of depth depends on whether a bipartite seed is found or not, or if it is manually ignored:

sage: it = S.variable_class_iter(depth=1, ignore_bipartite_belt=True)
sage: for T in it: print(T)
x0
x1
x2
(x1 + 1)/x2
(x0*x2 + 1)/x1
(x1 + 1)/x0

sage: S.mutate([0,1])
sage: it2 = S.variable_class_iter(depth=1)
sage: for T in it2: print(T)
(x1 + 1)/x0
(x0*x2 + x1 + 1)/(x0*x1)
x2
(x1^2 + x0*x2 + 2*x1 + 1)/(x0*x1*x2)
x1
(x0*x2 + 1)/x1
>>> from sage.all import *
>>> it = S.variable_class_iter(depth=Integer(1), ignore_bipartite_belt=True)
>>> for T in it: print(T)
x0
x1
x2
(x1 + 1)/x2
(x0*x2 + 1)/x1
(x1 + 1)/x0

>>> S.mutate([Integer(0),Integer(1)])
>>> it2 = S.variable_class_iter(depth=Integer(1))
>>> for T in it2: print(T)
(x1 + 1)/x0
(x0*x2 + x1 + 1)/(x0*x1)
x2
(x1^2 + x0*x2 + 2*x1 + 1)/(x0*x1*x2)
x1
(x0*x2 + 1)/x1

Infinite type examples:

sage: S = ClusterSeed(['A',[1,1],1])
sage: it = S.variable_class_iter(depth=2)
sage: for T in it: print(T)
Found a bipartite seed - restarting the depth counter at zero
and constructing the variable class using its bipartite belt.
x0
x1
(x1^2 + 1)/x0
(x1^4 + x0^2 + 2*x1^2 + 1)/(x0^2*x1)
(x0^4 + 2*x0^2 + x1^2 + 1)/(x0*x1^2)
(x0^2 + 1)/x1
(x1^6 + x0^4 + 2*x0^2*x1^2 + 3*x1^4 + 2*x0^2 + 3*x1^2 + 1)/(x0^3*x1^2)
(x1^8 + x0^6 + 2*x0^4*x1^2 + 3*x0^2*x1^4 + 4*x1^6 + 3*x0^4 + 6*x0^2*x1^2 + 6*x1^4 + 3*x0^2 + 4*x1^2 + 1)/(x0^4*x1^3)
(x0^8 + 4*x0^6 + 3*x0^4*x1^2 + 2*x0^2*x1^4 + x1^6 + 6*x0^4 + 6*x0^2*x1^2 + 3*x1^4 + 4*x0^2 + 3*x1^2 + 1)/(x0^3*x1^4)
(x0^6 + 3*x0^4 + 2*x0^2*x1^2 + x1^4 + 3*x0^2 + 2*x1^2 + 1)/(x0^2*x1^3)
>>> from sage.all import *
>>> S = ClusterSeed(['A',[Integer(1),Integer(1)],Integer(1)])
>>> it = S.variable_class_iter(depth=Integer(2))
>>> for T in it: print(T)
Found a bipartite seed - restarting the depth counter at zero
and constructing the variable class using its bipartite belt.
x0
x1
(x1^2 + 1)/x0
(x1^4 + x0^2 + 2*x1^2 + 1)/(x0^2*x1)
(x0^4 + 2*x0^2 + x1^2 + 1)/(x0*x1^2)
(x0^2 + 1)/x1
(x1^6 + x0^4 + 2*x0^2*x1^2 + 3*x1^4 + 2*x0^2 + 3*x1^2 + 1)/(x0^3*x1^2)
(x1^8 + x0^6 + 2*x0^4*x1^2 + 3*x0^2*x1^4 + 4*x1^6 + 3*x0^4 + 6*x0^2*x1^2 + 6*x1^4 + 3*x0^2 + 4*x1^2 + 1)/(x0^4*x1^3)
(x0^8 + 4*x0^6 + 3*x0^4*x1^2 + 2*x0^2*x1^4 + x1^6 + 6*x0^4 + 6*x0^2*x1^2 + 3*x1^4 + 4*x0^2 + 3*x1^2 + 1)/(x0^3*x1^4)
(x0^6 + 3*x0^4 + 2*x0^2*x1^2 + x1^4 + 3*x0^2 + 2*x1^2 + 1)/(x0^2*x1^3)
x(k)[source]#

Return the \(k\) -th initial cluster variable for the associated cluster seed, or the cluster variable of the corresponding vertex in self.quiver.

EXAMPLES:

sage: S = ClusterSeed(['A', 3])
sage: S.mutate([2, 1])
sage: S.x(0)
x0

sage: S.x(1)
x1

sage: S.x(2)
x2

sage: dg = DiGraph([['a', 'b'], ['b', 'c']], format="list_of_edges")
sage: S = ClusterSeed(dg, frozen=['c'])
sage: S.x(0)
a
sage: S.x('a')
a
>>> from sage.all import *
>>> S = ClusterSeed(['A', Integer(3)])
>>> S.mutate([Integer(2), Integer(1)])
>>> S.x(Integer(0))
x0

>>> S.x(Integer(1))
x1

>>> S.x(Integer(2))
x2

>>> dg = DiGraph([['a', 'b'], ['b', 'c']], format="list_of_edges")
>>> S = ClusterSeed(dg, frozen=['c'])
>>> S.x(Integer(0))
a
>>> S.x('a')
a
y(k)[source]#

Return the \(k\) -th initial coefficient (frozen variable) for the associated cluster seed, or the cluster variable of the corresponding vertex in self.quiver.

EXAMPLES:

sage: S = ClusterSeed(['A', 3]).principal_extension()
sage: S.mutate([2, 1])
sage: S.y(0)
y0

sage: S.y(1)
y1

sage: S.y(2)
y2

sage: dg = DiGraph([['a', 'b'], ['b', 'c']], format="list_of_edges")
sage: S = ClusterSeed(dg, frozen=['c'])
sage: S.y(0)
c
sage: S.y('c')
c
>>> from sage.all import *
>>> S = ClusterSeed(['A', Integer(3)]).principal_extension()
>>> S.mutate([Integer(2), Integer(1)])
>>> S.y(Integer(0))
y0

>>> S.y(Integer(1))
y1

>>> S.y(Integer(2))
y2

>>> dg = DiGraph([['a', 'b'], ['b', 'c']], format="list_of_edges")
>>> S = ClusterSeed(dg, frozen=['c'])
>>> S.y(Integer(0))
c
>>> S.y('c')
c
class sage.combinat.cluster_algebra_quiver.cluster_seed.ClusterVariable(parent, numerator, denominator, coerce=True, reduce=True, mutation_type=None, variable_type=None, xdim=0)[source]#

Bases: FractionFieldElement

This class is a thin wrapper for cluster variables in cluster seeds.

It provides the extra feature to store if a variable is frozen or not.

  • the associated positive root:

    sage: S = ClusterSeed(['A',3])
    sage: for T in S.variable_class_iter():
    ....:     print("{} {}".format(T, T.almost_positive_root()))
    x0 -alpha[1]
    x1 -alpha[2]
    x2 -alpha[3]
    (x1 + 1)/x0 alpha[1]
    (x1^2 + x0*x2 + 2*x1 + 1)/(x0*x1*x2) alpha[1] + alpha[2] + alpha[3]
    (x1 + 1)/x2 alpha[3]
    (x0*x2 + x1 + 1)/(x0*x1) alpha[1] + alpha[2]
    (x0*x2 + 1)/x1 alpha[2]
    (x0*x2 + x1 + 1)/(x1*x2) alpha[2] + alpha[3]
    
    >>> from sage.all import *
    >>> S = ClusterSeed(['A',Integer(3)])
    >>> for T in S.variable_class_iter():
    ...     print("{} {}".format(T, T.almost_positive_root()))
    x0 -alpha[1]
    x1 -alpha[2]
    x2 -alpha[3]
    (x1 + 1)/x0 alpha[1]
    (x1^2 + x0*x2 + 2*x1 + 1)/(x0*x1*x2) alpha[1] + alpha[2] + alpha[3]
    (x1 + 1)/x2 alpha[3]
    (x0*x2 + x1 + 1)/(x0*x1) alpha[1] + alpha[2]
    (x0*x2 + 1)/x1 alpha[2]
    (x0*x2 + x1 + 1)/(x1*x2) alpha[2] + alpha[3]
    
almost_positive_root()[source]#

Return the almost positive root associated to self if self is of finite type.

EXAMPLES:

sage: S = ClusterSeed(['A',3])
sage: for T in S.variable_class_iter():
....:     print("{} {}".format(T, T.almost_positive_root()))
x0 -alpha[1]
x1 -alpha[2]
x2 -alpha[3]
(x1 + 1)/x0 alpha[1]
(x1^2 + x0*x2 + 2*x1 + 1)/(x0*x1*x2) alpha[1] + alpha[2] + alpha[3]
(x1 + 1)/x2 alpha[3]
(x0*x2 + x1 + 1)/(x0*x1) alpha[1] + alpha[2]
(x0*x2 + 1)/x1 alpha[2]
(x0*x2 + x1 + 1)/(x1*x2) alpha[2] + alpha[3]
>>> from sage.all import *
>>> S = ClusterSeed(['A',Integer(3)])
>>> for T in S.variable_class_iter():
...     print("{} {}".format(T, T.almost_positive_root()))
x0 -alpha[1]
x1 -alpha[2]
x2 -alpha[3]
(x1 + 1)/x0 alpha[1]
(x1^2 + x0*x2 + 2*x1 + 1)/(x0*x1*x2) alpha[1] + alpha[2] + alpha[3]
(x1 + 1)/x2 alpha[3]
(x0*x2 + x1 + 1)/(x0*x1) alpha[1] + alpha[2]
(x0*x2 + 1)/x1 alpha[2]
(x0*x2 + x1 + 1)/(x1*x2) alpha[2] + alpha[3]
sage.combinat.cluster_algebra_quiver.cluster_seed.PathSubset(n, m)[source]#

Encode a maximal Dyck path from \((0,0)\) to \((n,m)\) (for \(n \geq m \geq 0\)) as a subset of \(\{0,1,2,..., 2n-1\}\).

The encoding is given by indexing horizontal edges by odd numbers and vertical edges by evens.

The horizontal between \((i,j)\) and \((i+1,j)\) is indexed by the odd number \(2*i+1\). The vertical between \((i,j)\) and \((i,j+1)\) is indexed by the even number \(2*j\).

EXAMPLES:

sage: from sage.combinat.cluster_algebra_quiver.cluster_seed import PathSubset
sage: PathSubset(4,0)
{1, 3, 5, 7}
sage: PathSubset(4,1)
{1, 3, 5, 6, 7}
sage: PathSubset(4,2)
{1, 2, 3, 5, 6, 7}
sage: PathSubset(4,3)
{1, 2, 3, 4, 5, 6, 7}
sage: PathSubset(4,4)
{0, 1, 2, 3, 4, 5, 6, 7}
>>> from sage.all import *
>>> from sage.combinat.cluster_algebra_quiver.cluster_seed import PathSubset
>>> PathSubset(Integer(4),Integer(0))
{1, 3, 5, 7}
>>> PathSubset(Integer(4),Integer(1))
{1, 3, 5, 6, 7}
>>> PathSubset(Integer(4),Integer(2))
{1, 2, 3, 5, 6, 7}
>>> PathSubset(Integer(4),Integer(3))
{1, 2, 3, 4, 5, 6, 7}
>>> PathSubset(Integer(4),Integer(4))
{0, 1, 2, 3, 4, 5, 6, 7}
sage.combinat.cluster_algebra_quiver.cluster_seed.SetToPath(T)[source]#

Rearrange the encoding for a maximal Dyck path (as a set) so that it is a list in the proper order of the edges.

EXAMPLES:

sage: from sage.combinat.cluster_algebra_quiver.cluster_seed import PathSubset
sage: from sage.combinat.cluster_algebra_quiver.cluster_seed import SetToPath
sage: SetToPath(PathSubset(4,0))
[1, 3, 5, 7]
sage: SetToPath(PathSubset(4,1))
[1, 3, 5, 7, 6]
sage: SetToPath(PathSubset(4,2))
[1, 3, 2, 5, 7, 6]
sage: SetToPath(PathSubset(4,3))
[1, 3, 2, 5, 4, 7, 6]
sage: SetToPath(PathSubset(4,4))
[1, 0, 3, 2, 5, 4, 7, 6]
>>> from sage.all import *
>>> from sage.combinat.cluster_algebra_quiver.cluster_seed import PathSubset
>>> from sage.combinat.cluster_algebra_quiver.cluster_seed import SetToPath
>>> SetToPath(PathSubset(Integer(4),Integer(0)))
[1, 3, 5, 7]
>>> SetToPath(PathSubset(Integer(4),Integer(1)))
[1, 3, 5, 7, 6]
>>> SetToPath(PathSubset(Integer(4),Integer(2)))
[1, 3, 2, 5, 7, 6]
>>> SetToPath(PathSubset(Integer(4),Integer(3)))
[1, 3, 2, 5, 4, 7, 6]
>>> SetToPath(PathSubset(Integer(4),Integer(4)))
[1, 0, 3, 2, 5, 4, 7, 6]
sage.combinat.cluster_algebra_quiver.cluster_seed.coeff_recurs(p, q, a1, a2, b, c)[source]#

Coefficients in Laurent expansion of greedy element, as defined by recursion.

EXAMPLES:

sage: from sage.combinat.cluster_algebra_quiver.cluster_seed import coeff_recurs
sage: coeff_recurs(1, 1, 5, 5, 3, 3)
10
>>> from sage.all import *
>>> from sage.combinat.cluster_algebra_quiver.cluster_seed import coeff_recurs
>>> coeff_recurs(Integer(1), Integer(1), Integer(5), Integer(5), Integer(3), Integer(3))
10
sage.combinat.cluster_algebra_quiver.cluster_seed.get_green_vertices(C)[source]#

Get the green vertices from a matrix.

Will go through each column and return the ones where no entry is greater than 0.

INPUT:

  • C – The C-matrix to check

EXAMPLES:

sage: from sage.combinat.cluster_algebra_quiver.cluster_seed import get_green_vertices
sage: S = ClusterSeed(['A',4]); S.mutate([1,2,3,2,0,1,2,0,3])
sage: get_green_vertices(S.c_matrix())
[0, 3]
>>> from sage.all import *
>>> from sage.combinat.cluster_algebra_quiver.cluster_seed import get_green_vertices
>>> S = ClusterSeed(['A',Integer(4)]); S.mutate([Integer(1),Integer(2),Integer(3),Integer(2),Integer(0),Integer(1),Integer(2),Integer(0),Integer(3)])
>>> get_green_vertices(S.c_matrix())
[0, 3]
sage.combinat.cluster_algebra_quiver.cluster_seed.get_red_vertices(C)[source]#

Get the red vertices from a matrix.

Will go through each column and return the ones where no entry is less than 0.

INPUT:

  • C – The C-matrix to check

EXAMPLES:

sage: from sage.combinat.cluster_algebra_quiver.cluster_seed import get_red_vertices
sage: S = ClusterSeed(['A',4]); S.mutate([1,2,3,2,0,1,2,0,3])
sage: get_red_vertices(S.c_matrix())
[1, 2]
>>> from sage.all import *
>>> from sage.combinat.cluster_algebra_quiver.cluster_seed import get_red_vertices
>>> S = ClusterSeed(['A',Integer(4)]); S.mutate([Integer(1),Integer(2),Integer(3),Integer(2),Integer(0),Integer(1),Integer(2),Integer(0),Integer(3)])
>>> get_red_vertices(S.c_matrix())
[1, 2]
sage.combinat.cluster_algebra_quiver.cluster_seed.is_LeeLiZel_allowable(T, n, m, b, c)[source]#

Check if the subset \(T\) contributes to the computation of the greedy element \(x[m,n]\) in the rank two \((b,c)\)-cluster algebra.

This uses the conditions of Lee-Li-Zelevinsky’s paper [LLZ2014].

EXAMPLES:

sage: from sage.combinat.cluster_algebra_quiver.cluster_seed import is_LeeLiZel_allowable
sage: is_LeeLiZel_allowable({1,3,2,5,7,6},4,2,6,6)
False
sage: is_LeeLiZel_allowable({1,2,5},3,3,1,1)
True
>>> from sage.all import *
>>> from sage.combinat.cluster_algebra_quiver.cluster_seed import is_LeeLiZel_allowable
>>> is_LeeLiZel_allowable({Integer(1),Integer(3),Integer(2),Integer(5),Integer(7),Integer(6)},Integer(4),Integer(2),Integer(6),Integer(6))
False
>>> is_LeeLiZel_allowable({Integer(1),Integer(2),Integer(5)},Integer(3),Integer(3),Integer(1),Integer(1))
True