Introduction to the Cluster Algebras Package

I. Background

The cluster algebras package was originally designed by Christian and Gregg for doing calculations related to cluster algebra mutations using Sage.  I'll get into exactly what the package can (and can't yet) do later.

All of you should be familiar with cluster algebras but let me remind you anyway about the basic construction:
The construction of a cluster algebra (of geometric type) begins with a seed (x,B) or (x,Q) where the cluster x is a collection of algebraically independent rational functions, B is an exchange matrix, and Q is a (valued) ice quiver.

The cluster algebra is then constructed by a process of mutations which simultaneously changes the cluster x and the exchange matrix B (or quiver) to produce a new seed.  This process is what has been implemented in Sage, the cluster algebra itself (i.e. the subalgebra generated by all cluster variables) and its structure as a ring are not yet present.

II. Accessing the Package

So you've downloaded and installed a version of Sage on your computer, where is the cluster package? ----->

sage/src/sage/combinat/cluster_algebra_quiver

What does this mean?  Well, the package lives in the combinat branch so that on a fresh install of Sage you have to work a little bit to access the package.  Salvatore should discuss tomorrow more about doing this properly using GIT and how to get your changes into the main Sage distribution.  For now the following commands will get you access to the package.

{{{id=19| lazy_import("sage.combinat.cluster_algebra_quiver.quiver_mutation_type", "QuiverMutationType") lazy_import("sage.combinat.cluster_algebra_quiver.quiver", "ClusterQuiver") lazy_import("sage.combinat.cluster_algebra_quiver.cluster_seed", "ClusterSeed") /// }}}

Now we can begin doing calculations.

III. What It Can Do (Well)

There are many ways to construct a seed using the cluster package.  I'll run through exactly what they are later, for now let's see how it works.  How about a few examples given by specifying types:

{{{id=20| S1 = ClusterSeed(['A',5]); S1 /// A seed for a cluster algebra of rank 5 of type ['A', 5] }}} {{{id=66| S1.interact() /// }}} {{{id=31| S2 = ClusterSeed(['A',[2,5],1]); S2 /// A seed for a cluster algebra of rank 7 of type ['A', [2, 5], 1] }}} {{{id=67| S2.show() /// }}} {{{id=32| S3 = ClusterSeed(['GR',[3,7]]); S3 /// A seed for a cluster algebra of rank 6 of type ['E', 6] }}} {{{id=33| S4 = ClusterSeed(['E',6]); S4 /// A seed for a cluster algebra of rank 6 of type ['E', 6] }}}

And some given by specifying the exchange matrix:

{{{id=34| B = matrix([[0,2],[-4,0]]) S5 = ClusterSeed(B) print S5 S5.b_matrix() /// A seed for a cluster algebra of rank 2 [ 0 2] [-4 0] }}} {{{id=36| B = matrix([[0,3],[-1,0],[1,0]]) S6 = ClusterSeed(B) print S6 S6.mutation_type() /// A seed for a cluster algebra of rank 2 with 1 frozen variable ['G', 2] }}}

In this last example we see one of the primary features of the cluster package, i.e. an intricate system of type checking.  We did not tell the package that this seed was of type G2 but the package discovered this.

What about the two type E6 examples above?  Did we produce the same seed by these constructions?

{{{id=40| S3 == S4 /// False }}}

So what is the difference?  Each seed produced by specifying a type has a standardized exchange matrix/quiver associated to it, let's see in these examples:

{{{id=63| S3.plot() /// }}} {{{id=64| S4.plot() /// }}} {{{id=43| S4 = ClusterSeed(['E',6]) S4.quiver().interact() /// }}} {{{id=44| S3 = ClusterSeed(['GR',[3,7]]) S3.quiver().interact() #mutate in directions 4,1,0,2 /// }}}

Somehow the cluster package knew that these quivers produced mutation equivalent seeds, this is one of the major features of the package.  It "knows" all of the finite-type, affine-type, and mutation-finite seeds.  The bulk of the package goes towards this intricate system of type-checking.  Let's see what it can do:

{{{id=56| S3 = ClusterSeed(['GR',[3,7]]) print "Acyclic?", S3.is_acyclic() print "Bipartite?", S3.is_bipartite() print "Finite Type?", S3.is_finite() #by checking the type print "Finite Mutation Type?", S3.is_mutation_finite() #by random sequence of mutations /// Acyclic? False Bipartite? False Finite Type? True Finite Mutation Type? True }}} {{{id=60| B = matrix([[0,2,-2],[-2,0,2],[2,-2,0]]) S7 = ClusterSeed(B) print "Acyclic?", S7.is_acyclic() print "Bipartite?", S7.is_bipartite() print "Finite Type?", S7.is_finite() print "Finite Mutation Type?", S7.is_mutation_finite() S7.mutation_type() /// Acyclic? False Bipartite? False Finite Type? False Finite Mutation Type? True 'undetermined finite mutation type' }}} {{{id=57| B = matrix([[0,2],[-4,0]]) S5 = ClusterSeed(B) print "Acyclic?", S5.is_acyclic() print "Bipartite?", S5.is_bipartite() print "Finite Type?", S5.is_finite() print "Finite Mutation Type?", S5.is_mutation_finite() S5.mutation_type() /// Acyclic? True Bipartite? True Finite Type? False Finite Mutation Type? False 'undetermined infinite mutation type' }}}

**This shows a small bug in the  is_mutation_finite()  method.

Applying a similar random search procedure, one could add an  is_mutation_acyclic()  method.

IV. What It Can Do (Needs some work)

The standard seeds have no coefficients as we can see from the square exchange matrices.  You can add coefficients manually be editting the quiver directly or you can principalize any given seed, notice that the frozen vertices show up in blue an cannot be mutated.

{{{id=46| S1 = ClusterSeed(['A',5]) S1P = S1.principal_extension() S1P.interact() #mutate in directions 2,1,2,3,2,1 /// }}}

Now that we have a seed with principal coefficients we can compute things like c-vectors, g-vectors, and F-polynomials.

{{{id=49| print "C=" print S1P.c_matrix() print "G=" print S1P.g_matrix() S1P.f_polynomials() /// C= [ 1 0 0 0 0] [ 0 0 1 -1 0] [ 0 0 0 -1 0] [ 0 -1 0 0 0] [ 0 0 0 0 1] G= [ 1 0 0 0 0] [ 0 0 1 0 0] [ 0 0 -1 -1 0] [ 0 -1 0 0 0] [ 0 0 0 0 1] [1, y3 + 1, y2*y3 + y2 + 1, y1*y2*y3 + y1*y2 + y2*y3 + y2 + 1, 1] }}}

This functions by computing the cluster variables and then obtaining g-vectors and F-polynomials by specialization.  The method implemented will not work for arbitrary exchange matrices.  Fortunately, Fomin and Zelevinsky have worked out recursions for c-vectors, g-vectors, and F-polynomials in CA4 which should be implemented instead of this specialization.

V. Some of My Projects Planned for This Week

1. Implement c-vector, g-vector, and F-polynomial recursions.  Harold should be giving the mathematical background for this later today.


2. This allows one to easily calculate cluster variables over arbitrary semi-fields, this should be implemented alongside the above recursions.

3. I have written some code for quantum cluster algebra computations that I would like to clean up and incorporate into the package.  This has required implementing a division algorithm for quantum tori.  In the case of acyclic initial seeds the naive division algorithm works to compute all quantum cluster variables.  For cyclic initial seeds the division algorithm can fail because of incorrect term order and needs to be modified to incorporate the grading of cluster variables by g-vectors.

Thank You and Happy Coding!



{{{id=65| /// }}}