Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
r""" Kleber Trees
A Kleber tree is a tree of weights generated by Kleber's algorithm [Kleber1]_. The nodes correspond to the weights in the positive Weyl chamber obtained by subtracting a (non-zero) positive root. The edges are labeled by the coefficients of the roots of the difference.
AUTHORS:
- Travis Scrimshaw (2011-05-03): Initial version - Travis Scrimshaw (2013-02-13): Added support for virtual trees and improved `\LaTeX` output
EXAMPLES::
sage: from sage.combinat.rigged_configurations.kleber_tree import KleberTree sage: KleberTree(['A', 3, 1], [[3,2], [2,1], [1,1], [1,1]]) Kleber tree of Cartan type ['A', 3, 1] and B = ((3, 2), (2, 1), (1, 1), (1, 1)) sage: KleberTree(['D', 4, 1], [[2,2]]) Kleber tree of Cartan type ['D', 4, 1] and B = ((2, 2),)
TESTS::
sage: from sage.combinat.rigged_configurations.kleber_tree import KleberTree sage: KT = KleberTree(['A', 3, 1], [[3,2], [2,1], [1,1], [1,1]]) sage: sorted((x.weight.to_vector(), x.up_root.to_vector()) for x in KT.list()) [((0, 0, 2), (1, 1, 0)), ((0, 0, 2), (2, 2, 1)), ((0, 1, 0), (0, 0, 1)), ((0, 1, 0), (1, 1, 1)), ((0, 2, 2), (1, 0, 0)), ((1, 0, 3), (1, 1, 0)), ((1, 1, 1), (1, 1, 1)), ((2, 0, 0), (0, 1, 1)), ((2, 1, 2), (0, 0, 0)), ((3, 0, 1), (0, 1, 1))]
sage: KT = KleberTree(['A', 7, 1], [[3,2], [2,1], [1,1]]) sage: KT Kleber tree of Cartan type ['A', 7, 1] and B = ((3, 2), (2, 1), (1, 1)) sage: sorted((x.weight.to_vector(), x.up_root.to_vector()) for x in KT.list()) [((0, 0, 0, 1, 1, 0, 0), (1, 1, 1, 0, 0, 0, 0)), ((0, 0, 1, 0, 0, 1, 0), (2, 3, 3, 2, 1, 0, 0)), ((0, 0, 3, 0, 0, 0, 0), (1, 1, 0, 0, 0, 0, 0)), ((0, 1, 1, 1, 0, 0, 0), (1, 1, 1, 0, 0, 0, 0)), ((1, 0, 0, 2, 0, 0, 0), (0, 1, 1, 0, 0, 0, 0)), ((1, 0, 1, 0, 1, 0, 0), (1, 2, 2, 1, 0, 0, 0)), ((1, 1, 2, 0, 0, 0, 0), (0, 0, 0, 0, 0, 0, 0)), ((2, 0, 1, 1, 0, 0, 0), (0, 1, 1, 0, 0, 0, 0))] """
#***************************************************************************** # Copyright (C) 2011, 2012 Travis Scrimshaw <tscrim@ucdavis.edu> # # Distributed under the terms of the GNU General Public License (GPL) # # This code is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # The full text of the GPL is available at: # # http://www.gnu.org/licenses/ #*****************************************************************************
from six.moves import range import itertools
from sage.misc.lazy_attribute import lazy_attribute from sage.misc.cachefunc import cached_method from sage.misc.latex import latex from sage.misc.misc_c import prod from sage.arith.all import binomial from sage.rings.integer import Integer from sage.rings.all import ZZ
from sage.structure.parent import Parent from sage.structure.element import Element from sage.structure.unique_representation import UniqueRepresentation from sage.structure.richcmp import richcmp_not_equal, richcmp from sage.categories.finite_enumerated_sets import FiniteEnumeratedSets from sage.modules.free_module import FreeModule
from sage.combinat.root_system.cartan_type import CartanType
from sage.graphs.digraph import DiGraph from sage.graphs.dot2tex_utils import have_dot2tex
###################################### # Latex method for viewing the trees # ######################################
def _draw_tree(tree_node, node_label=True, style_point=None, style_node='fill=white', style_line=None, hspace=2.5, vspace=-2.5, start=[0.,0.], rpos=[0.,0.], node_id=0, node_prefix='T', edge_labels=True, use_vector_notation=False): r""" Return the tikz latex for drawing the Kleber tree.
AUTHORS:
- Viviane Pons (2013-02-13): Initial version - Travis Scrimshaw (2013-03-02): Modified to work with Kleber tree output
.. WARNING::
Internal latex function.
EXAMPLES::
sage: from sage.combinat.rigged_configurations.kleber_tree import KleberTree sage: KT = KleberTree(['A',3,1], [[3,2],[1,1]]) sage: latex(KT) # indirect doctest \begin{tikzpicture} \node[fill=white] (T0) at (0.000, 0.000){$V_{\omega_{1}+2\omega_{3}}$}; \node (T00) at (0.000, -2.500){$V_{\omega_{3}}$}; \draw (T0) to node[sloped,above]{\tiny $\alpha_{1} + \alpha_{2} + \alpha_{3}$} (T00); \end{tikzpicture} """ else: r += "{};\n"
else: style_line_str = "[%s]"%style_line else: node_place_str = ".center"
# Getting children string pos[0] = start[0] start[0] += hspace pos[0] = rpos[0] else: else: lines_str += "\\draw%s (%s%s) -- (%s%s%s);\n"%(style_line_str, node_name, node_place_str, node_name, i, node_place_str)
#drawing root style_node = '' else: else: style_point = "[%s]"%style_point else: node_str += "{};\n" point_str = "\\draw%s (%s) circle;\n"%(style_point, node_name)
##################### # Kleber tree nodes # #####################
class KleberTreeNode(Element): r""" A node in the Kleber tree.
This class is meant to be used internally by the Kleber tree class and should not be created directly by the user.
For more on the Kleber tree and the nodes, see :class:`KleberTree`.
The dominating root is the ``up_root`` which is the difference between the parent node's weight and this node's weight.
INPUT:
- ``parent_obj`` -- The parent object of this element - ``node_weight`` -- The weight of this node - ``dominant_root`` -- The dominating root - ``parent_node`` -- (default:None) The parent node of this node """ def __init__(self, parent_obj, node_weight, dominant_root, parent_node=None): r""" Initialize the tree node.
TESTS::
sage: from sage.combinat.rigged_configurations.kleber_tree import KleberTree sage: RS = RootSystem(['A', 2]) sage: WS = RS.weight_lattice() sage: R = RS.root_lattice() sage: KT = KleberTree(['A', 2, 1], [[1,1]]) sage: parent = KT(WS.sum_of_terms([(1,5), (2,2)]), R.zero()) sage: parent Kleber tree node with weight [5, 2] and upwards edge root [0, 0] sage: parent.parent_node sage: child = KT(WS.sum_of_terms([(1,3), (2,1)]), R.sum_of_terms([(1,1), (2,2)]), parent) sage: child Kleber tree node with weight [3, 1] and upwards edge root [1, 2] sage: child.parent_node Kleber tree node with weight [5, 2] and upwards edge root [0, 0] sage: TestSuite(parent).run() """
@lazy_attribute def depth(self): """ Return the depth of this node in the tree.
EXAMPLES::
sage: from sage.combinat.rigged_configurations.kleber_tree import KleberTree sage: RS = RootSystem(['A', 2]) sage: WS = RS.weight_lattice() sage: R = RS.root_lattice() sage: KT = KleberTree(['A', 2, 1], [[1,1]]) sage: n = KT(WS.sum_of_terms([(1,5), (2,2)]), R.zero()) sage: n.depth 0 sage: n2 = KT(WS.sum_of_terms([(1,5), (2,2)]), R.zero(), n) sage: n2.depth 1 """
@cached_method def multiplicity(self): r""" Return the multiplicity of ``self``.
The multiplicity of a node `x` of depth `d` weight `\lambda` in a simply-laced Kleber tree is equal to:
.. MATH::
\prod_{i > 0} \prod_{a \in \overline{I}} \binom{p_i^{(a)} + m_i^{(a)}}{p_i^{(a)}}
Recall that
.. MATH::
m_i^{(a)} = \left( \lambda^{(i-1)} - 2 \lambda^{(i)} + \lambda^{(i+1)} \mid \overline{\Lambda}_a \right),
p_i^{(a)} = \left( \alpha_a \mid \lambda^{(i)} \right) - \sum_{j > i} (j - i) L_j^{(a)},
where `\lambda^{(i)}` is the weight node at depth `i` in the path to `x` from the root and we set `\lambda^{(j)} = \lambda` for all `j \geq d`.
Note that `m_i^{(a)} = 0` for all `i > d`.
EXAMPLES::
sage: from sage.combinat.rigged_configurations.kleber_tree import KleberTree sage: KT = KleberTree(['A',3,1], [[3,2],[2,1],[1,1],[1,1]]) sage: for x in KT: x, x.multiplicity() (Kleber tree node with weight [2, 1, 2] and upwards edge root [0, 0, 0], 1) (Kleber tree node with weight [3, 0, 1] and upwards edge root [0, 1, 1], 1) (Kleber tree node with weight [0, 2, 2] and upwards edge root [1, 0, 0], 1) (Kleber tree node with weight [1, 0, 3] and upwards edge root [1, 1, 0], 2) (Kleber tree node with weight [1, 1, 1] and upwards edge root [1, 1, 1], 4) (Kleber tree node with weight [0, 0, 2] and upwards edge root [2, 2, 1], 2) (Kleber tree node with weight [2, 0, 0] and upwards edge root [0, 1, 1], 2) (Kleber tree node with weight [0, 0, 2] and upwards edge root [1, 1, 0], 1) (Kleber tree node with weight [0, 1, 0] and upwards edge root [1, 1, 1], 2) (Kleber tree node with weight [0, 1, 0] and upwards edge root [0, 0, 1], 1)
TESTS:
We check that :trac:`16057` is fixed::
sage: RC = RiggedConfigurations(['D',4,1], [[1,3],[3,3],[4,3]]) sage: sum(x.multiplicity() for x in RC.kleber_tree()) == len(RC.module_generators) True """ # The multiplicity corresponding to the root is always 1
def __hash__(self): r""" TESTS::
sage: from sage.combinat.rigged_configurations.kleber_tree import KleberTree sage: RS = RootSystem(['A', 2]) sage: WS = RS.weight_lattice() sage: R = RS.root_lattice() sage: KT = KleberTree(['A', 2, 1], [[1,1]]) sage: n = KT(WS.sum_of_terms([(1,5), (2,2)]), R.zero()) sage: hash(n) -603608031356818252 # 64-bit -1956156236 # 32-bit """
def _richcmp_(self, rhs, op): r""" Check whether two nodes are equal.
TESTS::
sage: from sage.combinat.rigged_configurations.kleber_tree import KleberTree sage: RS = RootSystem(['A', 2]) sage: WS = RS.weight_lattice() sage: R = RS.root_lattice() sage: KT = KleberTree(['A', 2, 1], [[1,1]]) sage: n = KT(WS.sum_of_terms([(1,5), (2,2)]), R.zero()) sage: n2 = KT(WS.sum_of_terms([(1,5), (2,2)]), R.zero(), n) sage: n2 > n True sage: n3 = KT(WS.sum_of_terms([(1,5), (2,2)]), R.zero(), n) sage: n2 == n3 True sage: n3 = KT(WS.sum_of_terms([(1,5), (2,3)]), R.zero(), n) sage: n2 < n3 True """
def _repr_(self): r""" Return the string representation of ``self``.
EXAMPLES::
sage: from sage.combinat.rigged_configurations.kleber_tree import KleberTree sage: RS = RootSystem(['A', 3]) sage: WS = RS.weight_lattice() sage: R = RS.root_lattice() sage: KT = KleberTree(['A', 2, 1], [[1,1]]) sage: node = KT(WS.sum_of_terms([(1,2), (2,1), (3,1)]), R.sum_of_terms([(1,3), (3,3)])); node Kleber tree node with weight [2, 1, 1] and upwards edge root [3, 0, 3]
With virtual nodes::
sage: from sage.combinat.rigged_configurations.kleber_tree import VirtualKleberTree sage: KT = VirtualKleberTree(['A',6,2], [[2,2]]) sage: KT.root Kleber tree node with weight [0, 2, 0, 2, 0] and upwards edge root [0, 0, 0, 0, 0] """ list(self.weight.to_vector()), list(self.up_root.to_vector()) )
def _latex_(self): r""" Return latex representation of ``self``.
TESTS::
sage: from sage.combinat.rigged_configurations.kleber_tree import KleberTree sage: RS = RootSystem(['A', 3]) sage: WS = RS.weight_lattice() sage: R = RS.root_lattice() sage: KT = KleberTree(['A', 3, 1], [[3,2], [1,1]]) sage: node = KT(WS.sum_of_terms([(1,4), (3,1)]), R.zero()) sage: latex(node) V_{4\omega_{1}+\omega_{3}} sage: node = KT(WS.zero(), R.zero()) sage: latex(node) V_{0} sage: node = KT(WS.sum_of_terms([(1,2)]), R.zero()) sage: latex(node) V_{2\omega_{1}}
With virtual nodes::
sage: from sage.combinat.rigged_configurations.kleber_tree import VirtualKleberTree sage: KT = VirtualKleberTree(['C',3,1], [[2,2]]) sage: latex(KT.root) [V_{2\omega_{2}+2\omega_{4}}] sage: KT = VirtualKleberTree(['A',6,2], [[2,2]]) sage: latex(KT.root) [V_{2\omega_{2}+2\omega_{4}}] """ ret_str = repr(self.multiplicity()) + ret_str
else:
# Subtract 1 for indexing range(1, len(s_factors)) if s_factors[a] == gamma] else: L = []
####################### # Kleber tree classes # #######################
class KleberTree(UniqueRepresentation, Parent): r""" The tree that is generated by Kleber's algorithm.
A Kleber tree is a tree of weights generated by Kleber's algorithm [Kleber1]_. It is used to generate the set of all admissible rigged configurations for the simply-laced affine types `A_n^{(1)}`, `D_n^{(1)}`, `E_6^{(1)}`, `E_7^{(1)}`, and `E_8^{(1)}`.
.. SEEALSO::
There is a modified version for non-simply-laced affine types at :class:`VirtualKleberTree`.
The nodes correspond to the weights in the positive Weyl chamber obtained by subtracting a (non-zero) positive root. The edges are labeled by the coefficients of the roots, and `X` is a child of `Y` if `Y` is the root else if the edge label of `Y` to its parent `Z` is greater (in every component) than the label from `X` to `Y`.
For a Kleber tree, one needs to specify an affine (simply-laced) Cartan type and a sequence of pairs `(r,s)`, where `s` is any positive integer and `r` is a node in the Dynkin diagram. Each `(r,s)` can be viewed as a rectangle of width `s` and height `r`.
INPUT:
- ``cartan_type`` -- an affine simply-laced Cartan type
- ``B`` -- a list of dimensions of rectangles by `[r, c]` where `r` is the number of rows and `c` is the number of columns
REFERENCES:
.. [Kleber1] Michael Kleber. *Combinatorial structure of finite dimensional representations of Yangians: the simply-laced case*. Internat. Math. Res. Notices. (1997) no. 4. 187-201.
.. [Kleber2] Michael Kleber. *Finite dimensional representations of quantum affine algebras*. Ph.D. dissertation at University of California Berkeley. (1998). :arxiv:`math.QA/9809087`.
EXAMPLES:
Simply-laced example::
sage: from sage.combinat.rigged_configurations.kleber_tree import KleberTree sage: KT = KleberTree(['A', 3, 1], [[3,2], [1,1]]) sage: KT.list() [Kleber tree node with weight [1, 0, 2] and upwards edge root [0, 0, 0], Kleber tree node with weight [0, 0, 1] and upwards edge root [1, 1, 1]] sage: KT = KleberTree(['A', 3, 1], [[3,2], [2,1], [1,1], [1,1]]) sage: KT.cardinality() 10 sage: KT = KleberTree(['D', 4, 1], [[2,2]]) sage: KT.cardinality() 3 sage: KT = KleberTree(['D', 4, 1], [[4,5]]) sage: KT.cardinality() 1
From [Kleber2]_::
sage: KT = KleberTree(['E', 6, 1], [[4, 2]]) # long time (9s on sage.math, 2012) sage: KT.cardinality() # long time 12
We check that relabelled types work (:trac:`16876`)::
sage: ct = CartanType(['A',3,1]).relabel(lambda x: x+2) sage: kt = KleberTree(ct, [[3,1],[5,1]]) sage: list(kt) [Kleber tree node with weight [1, 0, 1] and upwards edge root [0, 0, 0], Kleber tree node with weight [0, 0, 0] and upwards edge root [1, 1, 1]] sage: kt = KleberTree(['A',3,1], [[1,1],[3,1]]) sage: list(kt) [Kleber tree node with weight [1, 0, 1] and upwards edge root [0, 0, 0], Kleber tree node with weight [0, 0, 0] and upwards edge root [1, 1, 1]] """ @staticmethod def __classcall_private__(cls, cartan_type, B, classical=None): """ Normalize the input arguments to ensure unique representation.
EXAMPLES::
sage: from sage.combinat.rigged_configurations.kleber_tree import KleberTree sage: KT1 = KleberTree(CartanType(['A',3,1]), [[2,2]]) sage: KT2 = KleberTree(['A',3,1], [(2,2)]) sage: KT3 = KleberTree(['A',3,1], ((2,2),)) sage: KT2 is KT1, KT3 is KT1 (True, True) """ raise ValueError("The Cartan type must be affine")
raise ValueError("use VirtualKleberTree for non-simply-laced types")
# Standardize B input into a tuple of tuples
else:
def __init__(self, cartan_type, B, classical_ct): r""" Construct a Kleber tree.
The input ``classical_ct`` is the classical Cartan type to run the algorithm on and is only meant to be used internally.
EXAMPLES::
sage: from sage.combinat.rigged_configurations.kleber_tree import KleberTree sage: KT = KleberTree(['D', 3, 1], [[1,1], [1,1]]); KT Kleber tree of Cartan type ['D', 3, 1] and B = ((1, 1), (1, 1)) sage: TestSuite(KT).run(skip="_test_elements") """
# Our computations in _children_iter_vector use dense vectors. # Moreover, ranks are relatively small, so just use the dense # version of the Cartan matrix. hspace=2.5, vspace=min(-2.5, -0.75*self._classical_ct.rank()))
def latex_options(self, **options): """ Return the current latex options if no arguments are passed, otherwise set the corresponding latex option.
OPTIONS:
- ``hspace`` -- (default: `2.5`) the horizontal spacing of the tree nodes - ``vspace`` -- (default: ``x``) the vertical spacing of the tree nodes, here ``x`` is the minimum of `-2.5` or `-.75n` where `n` is the rank of the classical type - ``edge_labels`` -- (default: ``True``) display edge labels - ``use_vector_notation`` -- (default: ``False``) display edge labels using vector notation instead of a linear combination
EXAMPLES::
sage: from sage.combinat.rigged_configurations.kleber_tree import KleberTree sage: KT = KleberTree(['D', 3, 1], [[2,1], [2,1]]) sage: KT.latex_options(vspace=-4, use_vector_notation=True) sage: sorted(KT.latex_options().items()) [('edge_labels', True), ('hspace', 2.5), ('use_vector_notation', True), ('vspace', -4)] """
def _latex_(self): r""" Return a latex representation of this Kleber tree.
.. SEEALSO::
:meth:`latex_options()`
EXAMPLES::
sage: from sage.combinat.rigged_configurations.kleber_tree import KleberTree sage: KT = KleberTree(['D', 3, 1], [[2,1], [2,1]]) sage: KT._latex_() '\\begin{tikzpicture}...\\end{tikzpicture}' """
_draw_tree(self.root, **self._latex_options) \ + "\\end{tikzpicture}"
def _build_tree(self): """ Build the Kleber tree.
TESTS:
This is called from the constructor::
sage: from sage.combinat.rigged_configurations.kleber_tree import KleberTree sage: KT = KleberTree(['A',3,1], [[2,2]]) # indirect doctest """ # Create an empty node at first step self._classical_ct.root_system().root_lattice().zero())
# Convert the B values into an L matrix
# Perform a special case of the algorithm for the root node
# self._has_normaliz is set by _children_iter else:
for x in leaves for new_child in child_itr(x) if not self._prune(new_child, depth)]
# Connect the new children into the tree
def _children_iter(self, node): r""" Iterate over the children of ``node``.
Helper iterator to iterate over all children, by generating and/or computing them, of the Kleber tree node.
We compute the children by computing integral points (expressed as simple roots) in the polytope given by the intersection of the negative root cone and shifted positive weight cone. More precisely, we rewrite the condition `\lambda - \mu \in Q^+`, for `\mu \in P^+`, as `\lambda - Q^+ = \mu \in P^+`.
INPUT:
- ``node`` -- the current node in the tree whose children we want to generate
TESTS::
sage: from sage.combinat.rigged_configurations.kleber_tree import KleberTree sage: KT = KleberTree(['D', 3, 1], [[1,1], [1,1]]) sage: for x in KT: x # indirect doctest Kleber tree node with weight [2, 0, 0] and upwards edge root [0, 0, 0] Kleber tree node with weight [0, 1, 1] and upwards edge root [1, 0, 0] Kleber tree node with weight [0, 0, 0] and upwards edge root [2, 1, 1]
sage: KT = KleberTree(['D', 4, 1], [[2,2]]) sage: KT[1] Kleber tree node with weight [0, 1, 0, 0] and upwards edge root [1, 2, 1, 1] sage: for x in KT: x Kleber tree node with weight [0, 2, 0, 0] and upwards edge root [0, 0, 0, 0] Kleber tree node with weight [0, 1, 0, 0] and upwards edge root [1, 2, 1, 1] Kleber tree node with weight [0, 0, 0, 0] and upwards edge root [1, 2, 1, 1] sage: for x in KT._children_iter(KT[1]): x Kleber tree node with weight [0, 0, 0, 0] and upwards edge root [1, 2, 1, 1] """ # It is faster to just cycle through than build the polytope and its # lattice points when we are sufficiently small # The number 500 comes from testing on my machine about where the # tradeoff occurs between the methods. However, this may grow as # the _children_iter_vector is further optimized.
# Construct the polytope by inequalities # Construct the shifted weight cone for i,col in enumerate(self._CM.columns())] # Construct the negative weight cone # Construct the bounds for the non-root nodes
self._has_normaliz = True
# Build the nodes from the polytope # Sort for a consistent ordering (it is typically a small list) remove_zeros=False)
def _children_iter_vector(self, node): r""" Iterate over the children of ``node``.
Helper iterator to iterate over all children, by generating and/or computing them, of the Kleber tree node. This implementation iterates over all possible uproot vectors.
.. SEEALSO::
:meth:`_children_iter`
INPUT:
- ``node`` -- the current node in the tree whose children we want to generate
TESTS::
sage: from sage.combinat.rigged_configurations.kleber_tree import KleberTree sage: KT = KleberTree(['D', 4, 1], [[2,2]]) sage: KT[1] Kleber tree node with weight [0, 1, 0, 0] and upwards edge root [1, 2, 1, 1] sage: for x in KT._children_iter(KT[1]): x Kleber tree node with weight [0, 0, 0, 0] and upwards edge root [1, 2, 1, 1] """
# Convert the list to the weight lattice
P._from_dict(wd), Q._from_dict(rd, remove_zeros=False), node)
def _prune(self, new_child, depth): r""" Return ``True`` if we are to prune the tree at ``new_child``.
This always returns ``False`` since we do not do any pruning.
EXAMPLES::
sage: from sage.combinat.rigged_configurations.kleber_tree import KleberTree sage: KT = KleberTree(['A', 2, 1], [[1,1]]) sage: KT._prune(KT.root, 0) False """
def breadth_first_iter(self): r""" Iterate over all nodes in the tree following a breadth-first traversal.
EXAMPLES::
sage: from sage.combinat.rigged_configurations.kleber_tree import KleberTree sage: KT = KleberTree(['A', 3, 1], [[2, 2], [2, 3]]) sage: for x in KT.breadth_first_iter(): x Kleber tree node with weight [0, 5, 0] and upwards edge root [0, 0, 0] Kleber tree node with weight [1, 3, 1] and upwards edge root [0, 1, 0] Kleber tree node with weight [0, 3, 0] and upwards edge root [1, 2, 1] Kleber tree node with weight [2, 1, 2] and upwards edge root [0, 1, 0] Kleber tree node with weight [1, 1, 1] and upwards edge root [0, 1, 0] Kleber tree node with weight [0, 1, 0] and upwards edge root [1, 2, 1] """
def depth_first_iter(self): r""" Iterate (recursively) over the nodes in the tree following a depth-first traversal.
EXAMPLES::
sage: from sage.combinat.rigged_configurations.kleber_tree import KleberTree sage: KT = KleberTree(['A', 3, 1], [[2, 2], [2, 3]]) sage: for x in KT.depth_first_iter(): x Kleber tree node with weight [0, 5, 0] and upwards edge root [0, 0, 0] Kleber tree node with weight [1, 3, 1] and upwards edge root [0, 1, 0] Kleber tree node with weight [2, 1, 2] and upwards edge root [0, 1, 0] Kleber tree node with weight [0, 3, 0] and upwards edge root [1, 2, 1] Kleber tree node with weight [1, 1, 1] and upwards edge root [0, 1, 0] Kleber tree node with weight [0, 1, 0] and upwards edge root [1, 2, 1] """
def _depth_first_iter(self, cur): r""" Helper recursive function used in depth-first iteration.
EXAMPLES::
sage: from sage.combinat.rigged_configurations.kleber_tree import KleberTree sage: KT = KleberTree(['A', 3, 1], [[2, 2], [2, 3]]) sage: for x in KT._depth_first_iter(None): x Kleber tree node with weight [0, 5, 0] and upwards edge root [0, 0, 0] Kleber tree node with weight [1, 3, 1] and upwards edge root [0, 1, 0] Kleber tree node with weight [2, 1, 2] and upwards edge root [0, 1, 0] Kleber tree node with weight [0, 3, 0] and upwards edge root [1, 2, 1] Kleber tree node with weight [1, 1, 1] and upwards edge root [0, 1, 0] Kleber tree node with weight [0, 1, 0] and upwards edge root [1, 2, 1] """
__iter__ = breadth_first_iter
def _repr_(self): """ Return a text representation of this Kleber tree.
EXAMPLES::
sage: from sage.combinat.rigged_configurations.kleber_tree import KleberTree sage: KleberTree(['D', 4, 1], [[2, 2]]) # indirect doctest Kleber tree of Cartan type ['D', 4, 1] and B = ((2, 2),) """
def cartan_type(self): r""" Return the Cartan type of this Kleber tree.
EXAMPLES::
sage: from sage.combinat.rigged_configurations.kleber_tree import KleberTree sage: KT = KleberTree(['A', 3, 1], [[1,1]]) sage: KT.cartan_type() ['A', 3, 1] """
def digraph(self): r""" Return a DiGraph representation of this Kleber tree.
EXAMPLES::
sage: from sage.combinat.rigged_configurations.kleber_tree import KleberTree sage: KT = KleberTree(['D', 4, 1], [[2, 2]]) sage: KT.digraph() Digraph on 3 vertices """
G.set_latex_options(format="dot2tex", edge_labels=True)
def plot(self, **options): """ Return the plot of self as a directed graph.
EXAMPLES::
sage: from sage.combinat.rigged_configurations.kleber_tree import KleberTree sage: KT = KleberTree(['D', 4, 1], [[2, 2]]) sage: print(KT.plot()) Graphics object consisting of 8 graphics primitives """
def _element_constructor_(self, node_weight, dominant_root, parent_node=None): """ Construct a Kleber tree node.
EXAMPLES::
sage: from sage.combinat.rigged_configurations.kleber_tree import KleberTree sage: RS = RootSystem(['A', 2]) sage: WS = RS.weight_lattice() sage: R = RS.root_lattice() sage: KT = KleberTree(['A', 2, 1], [[1,1]]) sage: root = KT(WS.sum_of_terms([(1,5), (2,2)]), R.zero()); root # indirect doctest Kleber tree node with weight [5, 2] and upwards edge root [0, 0] sage: child = KT(WS.sum_of_terms([(1,5), (2,1)]), R.zero(), root); child # indirect doctest Kleber tree node with weight [5, 1] and upwards edge root [0, 0] sage: child.parent_node Kleber tree node with weight [5, 2] and upwards edge root [0, 0] """
Element = KleberTreeNode
class VirtualKleberTree(KleberTree): """ A virtual Kleber tree.
We can use a modified version of the Kleber algorithm called the virtual Kleber algorithm [OSS03]_ to compute all admissible rigged configurations for non-simply-laced types. This uses the following embeddings into the simply-laced types:
.. MATH::
C_n^{(1)}, A_{2n}^{(2)}, A_{2n}^{(2)\dagger}, D_{n+1}^{(2)} \hookrightarrow A_{2n-1}^{(1)}
A_{2n-1}^{(2)}, B_n^{(1)} \hookrightarrow D_{n+1}^{(1)}
E_6^{(2)}, F_4^{(1)} \hookrightarrow E_6^{(1)}
D_4^{(3)}, G_2^{(1)} \hookrightarrow D_4^{(1)}
One then selects the subset of admissible nodes which are translates of the virtual requirements. In the graph, the selected nodes are indicated by brackets `[]`.
.. NOTE::
Because these are virtual nodes, all information is given in the corresponding simply-laced type.
.. SEEALSO::
For more on the Kleber algorithm, see :class:`KleberTree`.
REFERENCES:
.. [OSS03] Masato Okado, Anne Schilling, and Mark Shimozono. *Virtual crystals and Klebers algorithm*. Commun. Math. Phys. **238** (2003). 187-209. :arxiv:`math.QA/0209082`.
INPUT:
- ``cartan_type`` -- an affine non-simply-laced Cartan type
- ``B`` -- a list of dimensions of rectangles by `[r, c]` where `r` is the number of rows and `c` is the number of columns
EXAMPLES::
sage: from sage.combinat.rigged_configurations.kleber_tree import VirtualKleberTree sage: KT = VirtualKleberTree(['C', 4, 1], [[2,2]]) sage: KT.cardinality() 3 sage: KT.base_tree().cardinality() 6 sage: KT = VirtualKleberTree(['C', 4, 1], [[4,5]]) sage: KT.cardinality() 1 sage: KT = VirtualKleberTree(['D', 5, 2], [[2,1], [1,1]]) sage: KT.cardinality() 8 sage: KT = VirtualKleberTree(CartanType(['A', 4, 2]).dual(), [[1,1], [2,2]]) sage: KT.cardinality() 15 """ @staticmethod def __classcall_private__(cls, cartan_type, B): """ Normalize the input arguments to ensure unique representation.
EXAMPLES::
sage: from sage.combinat.rigged_configurations.kleber_tree import VirtualKleberTree sage: KT1 = VirtualKleberTree(CartanType(['C',3,1]).as_folding(), [[2,2]]) sage: KT2 = VirtualKleberTree(CartanType(['C',3,1]), [(2,2)]) sage: KT3 = VirtualKleberTree(['C',3,1], ((2,2),)) sage: KT2 is KT1, KT3 is KT1 (True, True) """ # Standardize B input into a tuple of tuples # Types A_{2n}^{(2)} and its dual raise ValueError("use KleberTree for simply-laced types")
def __init__(self, cartan_type, B): """ Initialize ``self``.
EXAMPLES::
sage: from sage.combinat.rigged_configurations.kleber_tree import VirtualKleberTree sage: KT = VirtualKleberTree(['C',4,1], [[2,2]]) sage: TestSuite(KT).run(skip="_test_elements") """
def _repr_(self): """ Return a text representation of this Kleber tree.
EXAMPLES::
sage: from sage.combinat.rigged_configurations.kleber_tree import VirtualKleberTree sage: VirtualKleberTree(['C', 4, 1], [[2, 2]]) Virtual Kleber tree of Cartan type ['C', 4, 1] and B = ((2, 2),) """
def _prune(self, new_child, depth): r""" Return ``True`` if we are to prune the tree at ``new_child``.
Suppose `\lambda` is the weight of the child we want to add at depth `\ell`. We prune ``new_child`` if either of the following conditions are not satisfied:
1. `(\lambda \mid \alpha_a) = (\lambda \mid \alpha_b)` if `a` and `b` are in the same `\sigma`-orbit. 2. If `\ell - 1 \notin \gamma_a \ZZ`, then the `a`-th component of ``up_root`` of ``new_child`` must equal the `a`-th component of ``up_root`` of its ``parent_node``. Note that from condition 1, we only need to check one such `a` from each `\sigma`-orbit.
These conditions are equivalent to Definition 4.1 in [OSS03]_.
EXAMPLES::
sage: from sage.combinat.rigged_configurations.kleber_tree import VirtualKleberTree sage: RS = RootSystem(['A', 3]) sage: WS = RS.weight_lattice() sage: R = RS.root_lattice() sage: KT = VirtualKleberTree(['C',2,1], [[1,2],[1,1],[2,1]]) sage: x = KT(WS.sum_of_terms([(1,1), (2,1), (3,3)]), R.sum_of_terms([(1,2),(2,2),(3,1)]), KT.root) sage: KT._prune(x, 1) True """ != new_child.parent_node.up_root[sigma[a][0]]:
def breadth_first_iter(self, all_nodes=False): r""" Iterate over all nodes in the tree following a breadth-first traversal.
INPUT:
- ``all_nodes`` -- (default: ``False``) if ``True``, output all nodes in the tree
EXAMPLES::
sage: from sage.combinat.rigged_configurations.kleber_tree import VirtualKleberTree sage: KT = VirtualKleberTree(['C', 2, 1], [[1,1], [2,1]]) sage: for x in KT.breadth_first_iter(): x Kleber tree node with weight [1, 2, 1] and upwards edge root [0, 0, 0] Kleber tree node with weight [1, 0, 1] and upwards edge root [0, 1, 0] sage: for x in KT.breadth_first_iter(True): x Kleber tree node with weight [1, 2, 1] and upwards edge root [0, 0, 0] Kleber tree node with weight [0, 2, 0] and upwards edge root [1, 1, 1] Kleber tree node with weight [1, 0, 1] and upwards edge root [0, 1, 0] """ # Subtract 1 for indexing if s_factors[a] == gamma] else:
def depth_first_iter(self, all_nodes=False): r""" Iterate (recursively) over the nodes in the tree following a depth-first traversal.
INPUT:
- ``all_nodes`` -- (default: ``False``) if ``True``, output all nodes in the tree
EXAMPLES::
sage: from sage.combinat.rigged_configurations.kleber_tree import VirtualKleberTree sage: KT = VirtualKleberTree(['C', 2, 1], [[1,1], [2,1]]) sage: for x in KT.depth_first_iter(): x Kleber tree node with weight [1, 2, 1] and upwards edge root [0, 0, 0] Kleber tree node with weight [1, 0, 1] and upwards edge root [0, 1, 0] sage: for x in KT.depth_first_iter(True): x Kleber tree node with weight [1, 2, 1] and upwards edge root [0, 0, 0] Kleber tree node with weight [0, 2, 0] and upwards edge root [1, 1, 1] Kleber tree node with weight [1, 0, 1] and upwards edge root [0, 1, 0] """ # Subtract 1 for indexing if s_factors[a] == gamma] else: L = []
__iter__ = breadth_first_iter
def base_tree(self): """ Return the underlying virtual Kleber tree associated to ``self``.
EXAMPLES::
sage: from sage.combinat.rigged_configurations.kleber_tree import VirtualKleberTree sage: KT = VirtualKleberTree(['C', 4, 1], [[2,2]]) sage: KT.base_tree() Kleber tree of Cartan type ['A', 7, 1] and B = ((2, 2), (6, 2)) """
class KleberTreeTypeA2Even(VirtualKleberTree): r""" Kleber tree for types `A_{2n}^{(2)}` and `A_{2n}^{(2)\dagger}`.
Note that here for `A_{2n}^{(2)}` we use `\tilde{\gamma}_a` in place of `\gamma_a` in constructing the virtual Kleber tree, and so we end up selecting all nodes since `\tilde{\gamma}_a = 1` for all `a \in \overline{I}`. For type `A_{2n}^{(2)\dagger}`, we have `\gamma_a = 1` for all `a \in \overline{I}`.
.. SEEALSO::
:class:`VirtualKleberTree` """ @staticmethod def __classcall_private__(cls, cartan_type, B): """ Normalize the input arguments to ensure unique representation.
EXAMPLES::
sage: from sage.combinat.rigged_configurations.kleber_tree import VirtualKleberTree sage: KT1 = VirtualKleberTree(CartanType(['A',6,2]), [[2,2]]) sage: KT2 = VirtualKleberTree(['A',6,2], [(2,2)]) sage: KT3 = VirtualKleberTree(['A',6,2], ((2,2),)) sage: KT2 is KT1, KT3 is KT1 (True, True) """ # Standardize B input into a tuple of tuples
def __init__(self, cartan_type, B): """ Initialize ``self``.
EXAMPLES::
sage: from sage.combinat.rigged_configurations.kleber_tree import VirtualKleberTree sage: KT = VirtualKleberTree(['A',6,2], [[2,2]]); KT Virtual Kleber tree of Cartan type ['BC', 3, 2] and B = ((2, 2),) sage: TestSuite(KT).run(skip="_test_elements") """ else:
def __iter__(self): """ Iterate over all of the nodes.
EXAMPLES::
sage: from sage.combinat.rigged_configurations.kleber_tree import VirtualKleberTree sage: KT = VirtualKleberTree(['A',6,2], [[2,2]]) sage: L = [x for x in KT] sage: len(L) == KT.cardinality() True """
def _prune(self, new_child, depth): r""" Return ``True`` if we are to prune the tree at ``new_child``.
Suppose `\lambda` is the weight of the child we want to add at depth `\ell`. We prune ``new_child`` if `(\lambda \mid \alpha_a) \neq (\lambda \mid \alpha_b)` if `a` and `b` are in the same `\sigma`-orbit.
These conditions are equivalent to Definition 4.1 in [OSS03]_ by using `\tilde{\gamma}`, and since `\tilde{\gamma}_a = 1` for all `a`, the second condition becomes vacuous.
EXAMPLES::
sage: from sage.combinat.rigged_configurations.kleber_tree import VirtualKleberTree sage: RS = RootSystem(['A', 5]) sage: WS = RS.weight_lattice() sage: R = RS.root_lattice() sage: KT = VirtualKleberTree(['A',6,2], [[2,2]]) sage: x = KT(WS.sum_of_terms([(2,1), (4,1)]), R.sum_of_terms([(1,1),(2,2),(3,2),(4,2),(5,1)]), KT.root) sage: KT._prune(x, 1) False """
def breadth_first_iter(self, all_nodes=False): r""" Iterate over all nodes in the tree following a breadth-first traversal.
INPUT:
- ``all_nodes`` -- (default: ``False``) if ``True``, output all nodes in the tree
EXAMPLES::
sage: from sage.combinat.rigged_configurations.kleber_tree import VirtualKleberTree sage: KT = VirtualKleberTree(['A', 4, 2], [[2,1]]) sage: for x in KT.breadth_first_iter(): x Kleber tree node with weight [0, 2, 0] and upwards edge root [0, 0, 0] Kleber tree node with weight [1, 0, 1] and upwards edge root [0, 1, 0] Kleber tree node with weight [0, 0, 0] and upwards edge root [1, 2, 1] sage: for x in KT.breadth_first_iter(True): x Kleber tree node with weight [0, 2, 0] and upwards edge root [0, 0, 0] Kleber tree node with weight [1, 0, 1] and upwards edge root [0, 1, 0] Kleber tree node with weight [0, 0, 0] and upwards edge root [1, 2, 1] """
def depth_first_iter(self, all_nodes=False): r""" Iterate (recursively) over the nodes in the tree following a depth-first traversal.
INPUT:
- ``all_nodes`` -- (default: ``False``) if ``True``, output all nodes in the tree
EXAMPLES::
sage: from sage.combinat.rigged_configurations.kleber_tree import VirtualKleberTree sage: KT = VirtualKleberTree(['A', 4, 2], [[2,1]]) sage: for x in KT.depth_first_iter(): x Kleber tree node with weight [0, 2, 0] and upwards edge root [0, 0, 0] Kleber tree node with weight [1, 0, 1] and upwards edge root [0, 1, 0] Kleber tree node with weight [0, 0, 0] and upwards edge root [1, 2, 1] sage: for x in KT.depth_first_iter(True): x Kleber tree node with weight [0, 2, 0] and upwards edge root [0, 0, 0] Kleber tree node with weight [1, 0, 1] and upwards edge root [0, 1, 0] Kleber tree node with weight [0, 0, 0] and upwards edge root [1, 2, 1] """
|