Ticket #5794: trac_5794-revised.patch

File trac_5794-revised.patch, 71.4 KB (added by bump, 13 years ago)
  • sage/combinat/crystals/crystals.py

    # HG changeset patch
    # User Daniel Bump <bump@match.stanford.edu>
    # Date 1241641059 25200
    # Node ID 1d0aad0e44ac9634fe3eccadb94b28d69d947c0d
    # Parent  11e58081efbf19a8f073d4c08c4f3f913d62de35
    Reducible root system fixes and branching rule improvements
    
    diff --git a/sage/combinat/crystals/crystals.py b/sage/combinat/crystals/crystals.py
    a b  
    307307            sage: C = CrystalOfLetters(['A',2])
    308308            sage: T = TensorProductOfCrystals(C, C)
    309309            sage: A2 = WeylCharacterRing(C.cartan_type()); A2
    310             The Weyl Character Ring of Type [A,2] with Integer Ring coefficients
     310            The Weyl Character Ring of Type ['A', 2] with Integer Ring coefficients
    311311            sage: chi = T.character(A2); chi
    312312            A2(1,1,0) + A2(2,0,0)
    313313            sage: chi.check(verbose = true)
  • sage/combinat/root_system/cartan_type.py

    diff --git a/sage/combinat/root_system/cartan_type.py b/sage/combinat/root_system/cartan_type.py
    a b  
    460460        assert(len(t) == 2)
    461461        assert(t[0] in ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I'])
    462462        assert(t[1] in ZZ and t[1] >= 0)
    463         if t[0] in ['B', 'C']:
     463        if t[0] == 'D':
    464464            assert(t[1] >= 2)
    465         if t[0] == 'D':
    466             assert(t[1] >= 3)
    467465        if t[0] == 'E':
    468             assert(t[1] <= 8)
     466            assert(t[1] <= 8 and t[1] >= 6)
    469467        if t[0] == 'F':
    470             assert(t[1] <= 4)
     468            assert(t[1] == 4)
    471469        if t[0] == 'G':
    472             assert(t[1] <= 2)
     470            assert(t[1] == 2)
    473471        if t[0] == 'H':
    474472            assert(t[1] <= 4)
    475473
  • sage/combinat/root_system/type_A.py

    diff --git a/sage/combinat/root_system/type_A.py b/sage/combinat/root_system/type_A.py
    a b  
    106106        """
    107107        return self.sum(self.term(j) for j in range(i))
    108108
     109    def det(self, k=1):
     110        """
     111        returns the vector (1, ... ,1) which in the ['A',r]
     112        weight lattice, interpreted as a weight of GL(r+1,CC)
     113        is the determinant. If the optional parameter k is
     114        given, returns (k, ... ,k), the k-th power of the
     115        determinant.
     116
     117        EXAMPLES:
     118            sage: e = RootSystem(['A',3]).ambient_space()
     119            sage: e.det(1/2)
     120            (1/2, 1/2, 1/2, 1/2)
     121        """
     122        return self.sum(self.term(j)*k for j in range(self.n))
     123
    109124def dynkin_diagram(t):
    110125    """
    111126    Returns the graph corresponding to the Dynkin diagram
  • sage/combinat/root_system/type_reducible.py

    diff --git a/sage/combinat/root_system/type_reducible.py b/sage/combinat/root_system/type_reducible.py
    a b  
    33from sage.matrix.constructor import block_diagonal_matrix
    44from ambient_space import AmbientSpace
    55import sage.combinat.root_system as root_system
     6from sage.combinat.family import Family
    67
    78class CartanType(CartanType_abstract):
    89    r"""
     
    3031        self.affine = False
    3132        self._spaces = [t.root_system().ambient_space() for t in types]
    3233        self._shifts = [sum(l.n for l in self._spaces[:k]) for k in range(len(types))]
     34        # fails for dual root systems
     35        try:
     36            self._shifts.append(sum(t.root_system().ambient_space().dimension() for t in types))
     37        except:
     38            pass
    3339        self._rshifts = [sum(l[1] for l in types[:k]) for k in range(len(types))]
    3440        self.tools = root_system.type_reducible
    3541
     
    171177    EXAMPLES:
    172178        sage: RootSystem("A2xB2").ambient_space()
    173179        Ambient space of the Root system of type A2xB2
     180
    174181    """
    175182    def cartan_type(self):
    176183        """
     
    229236    def simple_roots(self):
    230237        """
    231238        EXAMPLES:
    232             sage: RootSystem("A1xA2").ambient_space().simple_roots()
    233             [(1, -1, 0, 0, 0), (0, 0, 1, -1, 0), (0, 0, 0, 1, -1)]
     239            sage: RootSystem("A1xB2").ambient_space().simple_roots()
     240            Finite family {1: (1, -1, 0, 0), 2: (0, 0, 1, -1), 3: (0, 0, 0, 1)}
    234241        """
    235242        res = []
    236243        for i, ambient_space in enumerate(self.ambient_spaces()):
    237244            res.extend(self.inject_weights(i, v) for v in ambient_space.simple_roots())
    238         return res
     245        return Family(dict([i,res[i-1]] for i in range(1,len(res)+1)))
     246
     247    def simple_coroots(self):
     248        """
     249        EXAMPLES:
     250            sage: RootSystem("A1xB2").ambient_space().simple_coroots()
     251            Finite family {1: (1, -1, 0, 0), 2: (0, 0, 1, -1), 3: (0, 0, 0, 2)}
     252        """
     253        cr = []
     254        for i, ambient_space in enumerate(self.ambient_spaces()):
     255            cr.extend(self.inject_weights(i, v) for v in ambient_space.simple_coroots())
     256        return Family(dict([i,cr[i-1]] for i in range(1,len(cr)+1)))
    239257
    240258    def positive_roots(self):
    241259        """
     
    263281        """
    264282        EXAMPLES:
    265283            sage: RootSystem("A2xB2").ambient_space().fundamental_weights()
    266             [(1, 0, 0, 0, 0), (1, 1, 0, 0, 0), (0, 0, 0, 1, 0), (0, 0, 0, 1/2, 1/2)]
     284            Finite family {1: (1, 0, 0, 0, 0), 2: (1, 1, 0, 0, 0), 3: (0, 0, 0, 1, 0), 4: (0, 0, 0, 1/2, 1/2)}
    267285        """
    268         ret = []
     286        fw = []
    269287        for i, ambient_space in enumerate(self.ambient_spaces()):
    270             ret.extend(self.inject_weights(i, v) for v in ambient_space.fundamental_weights())
    271         return ret
     288            fw.extend(self.inject_weights(i, v) for v in ambient_space.fundamental_weights())
     289        return Family(dict([i,fw[i-1]] for i in range(1,len(fw)+1)))
    272290
    273291def dynkin_diagram(t):
    274292    """
  • sage/combinat/root_system/weyl_characters.py

    diff --git a/sage/combinat/root_system/weyl_characters.py b/sage/combinat/root_system/weyl_characters.py
    a b  
    1717#*****************************************************************************
    1818import cartan_type
    1919from sage.combinat.root_system.root_system import RootSystem
     20from sage.combinat.root_system.cartan_type import CartanType
    2021from sage.modules.free_module import VectorSpace
    2122from sage.structure.element import is_Element
    2223from sage.rings.all import ZZ, QQ
    2324from sage.misc.misc import repr_lincomb
     25from sage.misc.functional import is_odd, is_even
     26from sage.misc.flatten import flatten
    2427from sage.algebras.algebra import Algebra
    2528from sage.algebras.algebra_element import AlgebraElement
    2629import sage.structure.parent_base
     
    4750    representations; or Zhelobenko, Compact Lie Groups and their
    4851    Representations.
    4952   
     53    Computations that you can do with these include computing their
     54    weight multiplicities, products (thus decomposing the tensor
     55    product of a representation into irreducibles) and branching
     56    rules (restriction to a smaller group).
     57
    5058    There is associated with K, L or G as above a lattice, the weight
    5159    lattice, whose elements (called weights) are characters of a Cartan
    5260    subgroup or subalgebra. There is an action of the Weyl group W on
     
    5866   
    5967    EXAMPLES::
    6068   
    61         sage: L = RootSystem(['A',2]).ambient_space()
     69        sage: L = RootSystem("A2").ambient_space()
    6270        sage: [fw1,fw2] = L.fundamental_weights()
    6371        sage: R = WeylCharacterRing(['A',2], prefix="R")
    6472        sage: [R(1),R(fw1),R(fw2)]
     
    101109       
    102110        EXAMPLES::
    103111       
    104             sage: R = WeylCharacterRing(['B',3], prefix = "R")
     112            sage: R = WeylCharacterRing("B3", prefix = "R")
    105113            sage: r =  R(1,1,0)
    106114            sage: r == loads(dumps(r))
    107115            True
     
    110118        self._hdict = hdict
    111119        self._mdict = mdict
    112120        self._parent = A
    113         self._lattice = A._lattice
     121        self._space = A._space
    114122
    115123    def __repr__(self):
    116124        """
    117125        EXAMPLES::
    118126       
    119127            sage: R = WeylCharacterRing(['B',3], prefix = "R")
    120             sage: [R(w) for w in R.lattice().fundamental_weights()]
     128            sage: [R(w) for w in R.fundamental_weights()]
    121129            [R(1,0,0), R(1,1,0), R(1/2,1/2,1/2)]
    122130        """
    123131        if self._hdict == {}:
    124132            return "0"
    125133        v = self._hdict.keys()
    126         # Just a workaround to keep the same sorting as before when
    127         # the dictionary was indexed by tuples
    128134        v.sort(key = lambda v: tuple(v.to_vector()))
    129135        return repr_lincomb([self._parent.irr_repr(k) for k in v], [self._hdict[k] for k in v])
    130136
     
    133139        EXAMPLES::
    134140       
    135141            sage: B3 = WeylCharacterRing(['B',3])
    136             sage: fw = [B3(w) for w in B3.lattice().fundamental_weights()]
     142            sage: fw = [B3(w) for w in B3.fundamental_weights()]
    137143            sage: sorted(fw)
    138144            [B3(1/2,1/2,1/2), B3(1,0,0), B3(1,1,0)]
    139145            sage: b = B3(1,0,0)
     
    220226        EXAMPLES::
    221227       
    222228            sage: B3 = WeylCharacterRing(['B',3])
    223             sage: [B3(x).degree() for x in B3.lattice().fundamental_weights()]
     229            sage: [B3(x).degree() for x in B3.fundamental_weights()]
    224230            [7, 21, 8]
    225231        """
    226232        return sum(self._mdict[k] for k in self._mdict)
     
    233239       
    234240        EXAMPLES::
    235241       
    236             sage: F4 = WeylCharacterRing(['F',4])
    237             sage: [F4(x).check(verbose = true) for x in F4.lattice().fundamental_weights()]
    238             [[52, 52], [1274, 1274], [273, 273], [26, 26]]
     242            sage: B4 = WeylCharacterRing("B4")
     243            sage: [B4(x).check(verbose = true) for x in B4.fundamental_weights()]
     244            [[9, 9], [36, 36], [84, 84], [16, 16]]
    239245        """
    240         theoretical = sum(self._hdict[k]*self._lattice.weyl_dimension(k) for k in self._hdict)
     246        theoretical = sum(self._hdict[k]*self._space.weyl_dimension(k) for k in self._hdict)
    241247        practical = sum(self._mdict[k] for k in self._mdict)
    242248        if verbose:
    243249            return [theoretical, practical]
     
    321327       
    322328            sage: B3 = WeylCharacterRing(['B',3])
    323329            sage: A2 = WeylCharacterRing(['A',2])
    324             sage: [B3(w).branch(A2,rule="levi") for w in B3.lattice().fundamental_weights()]
     330            sage: [B3(w).branch(A2,rule="levi") for w in B3.fundamental_weights()]
    325331            [A2(0,0,-1) + A2(0,0,0) + A2(1,0,0),
    326332             A2(0,-1,-1) + A2(0,0,-1) + A2(0,0,0) + A2(1,0,-1) + A2(1,0,0) + A2(1,1,0),
    327333             A2(-1/2,-1/2,-1/2) + A2(1/2,-1/2,-1/2) + A2(1/2,1/2,-1/2) + A2(1/2,1/2,1/2)]
     
    359365       
    360366            sage: B3 = WeylCharacterRing(['B',3])
    361367            sage: B3(2).parent()
    362             The Weyl Character Ring of Type [B,3] with Integer Ring coefficients
     368            The Weyl Character Ring of Type ['B', 3] with Integer Ring coefficients
    363369        """
    364370        return self._parent
    365371
    366372
    367 def WeylCharacterRing(ct, base_ring=ZZ, prefix=None, cache=False):
     373def WeylCharacterRing(ct, base_ring=ZZ, prefix=None, cache=False, style="lattice"):
    368374    r"""
    369375    A class for rings of Weyl characters. The Weyl character is a
    370376    character of a semisimple (or reductive) Lie group or algebra. They
     
    385391    - ``cache`` -  (default False) setting cache = True is a substantial
    386392      speedup at the expense of some memory.
    387393   
     394    - ``style`` - (default "lattice") can be set style = "coroots"
     395    to obtain an alternative representation of the elements.
     396
    388397    If no prefix specified, one is generated based on the Cartan type.
    389398    It is good to name the ring after the prefix, since then it can
    390399    parse its own output.
     
    392401    EXAMPLES::
    393402   
    394403        sage: G2 = WeylCharacterRing(['G',2])
    395         sage: [fw1,fw2] = G2.lattice().fundamental_weights()
     404        sage: [fw1,fw2] = G2.fundamental_weights()
    396405        sage: 2*G2(2*fw1+fw2)
    397406        2*G2(4,-1,-3)
    398407        sage: 2*G2(4,-1,-3)
     
    407416    EXAMPLES::
    408417   
    409418        sage: R = WeylCharacterRing(['B',3], prefix='R')
    410         sage: chi = R(R.lattice().fundamental_weights()[3]); chi
     419        sage: chi = R(R.fundamental_weights()[3]); chi
    411420        R(1/2,1/2,1/2)
    412421        sage: R(1/2,1/2,1/2) == chi
    413422        True
    414423   
    415     The multiplication in R corresponds to the product of characters,
    416     which you can use to determine the decomposition of tensor products
    417     into irreducibles. For example, let us compute the tensor product
     424    You may choose an alternative style of labeling the elements.
     425    If you create the ring with the option style="coroots" then
     426    the integers in the label are not the components of the
     427    highest weight vector, but rather the coefficients when
     428    the highest weight vector is decomposed into a product
     429    of irreducibles. These coefficients are the values of the
     430    coroots on the highest weight vector.
     431
     432    In the coroot style the Lie group or Lie algebra is treated as
     433    semisimple, so you lose the distinction between GL(n) and
     434    SL(n). It gives you output that is comparable to that
     435    in Tables of Dimensions, Indices and Branching Rules for
     436    Representations of Simple Lie Algebras (Marcel Dekker, 1981).
     437
     438    EXAMPLES::
     439   
     440        sage: B3 = WeylCharacterRing("B3",style="coroots")
     441        sage: [fw1,fw2,fw3]=B3.fundamental_weights()
     442        sage: fw1+fw3
     443        (3/2, 1/2, 1/2)
     444        sage: B3(fw1+fw3)
     445        B3(1,0,1)
     446        sage: B3(1,0,1)
     447        B3(1,0,1)
     448
     449    For type ['A',r], the coroot representation carries
     450    less information, since elements of the weight lattice
     451    that are orthogonal to the coroots are represented as
     452    zero. This means that with the default style you can
     453    represent the determinant, but not in the coroot style.
     454    In the coroot style, elements of the Weyl character
     455    ring represent characters of SL(r+1,CC), while in the default
     456    style, they represent characters of GL(r+1,CC).
     457
     458    EXAMPLES:
     459
     460        sage: A2 = WeylCharacterRing("A2")
     461        sage: L = A2.space()
     462        sage: [A2(L.det()), A2(L(0))]
     463        [A2(1,1,1), A2(0,0,0)]
     464        sage: A2(L.det()) == A2(L(0))
     465        False
     466        sage: A2 = WeylCharacterRing("A2", style="coroots")
     467        sage: [A2(L.det()), A2(L(0))]
     468        [A2(0,0), A2(0,0)]
     469        sage: A2(L.det()) == A2(L(0))
     470        True
     471
     472    The multiplication in a Weyl character ring corresponds to the product of
     473    characters, which you can use to determine the decomposition of tensor
     474    products into irreducibles. For example, let us compute the tensor product
    418475    of the standard and spin representations of Spin(7).
    419476   
    420477    EXAMPLES::
    421478   
    422         sage: B3 = WeylCharacterRing(['B',3])
    423         sage: [fw1,fw2,fw3]=B3.lattice().fundamental_weights()
     479        sage: B3 = WeylCharacterRing("B3")
     480        sage: [fw1,fw2,fw3]=B3.fundamental_weights()
    424481        sage: [B3(fw1).degree(),B3(fw3).degree()]
    425482        [7, 8]
    426483        sage: B3(fw1)*B3(fw3)
     
    432489    TESTS::
    433490   
    434491        sage: F4 = WeylCharacterRing(['F',4], cache = True)
    435         sage: [fw1,fw2,fw3,fw4] = F4.lattice().fundamental_weights()
     492        sage: [fw1,fw2,fw3,fw4] = F4.fundamental_weights()
    436493        sage: chi = F4(fw4); chi, chi.degree()
    437494        (F4(1,0,0,0), 26)
    438495        sage: chi^2
     
    450507        [[(1, 1, 1), 2],  [(1, 2, 0), 1],  [(1, 0, 2), 1],  [(2, 1, 0), 1],  [(2, 0, 1), 1],  [(0, 1, 2), 1],  [(0, 2, 1), 1]]
    451508    """
    452509    ct = cartan_type.CartanType(ct)
    453     return cache_wcr(ct, base_ring=base_ring, prefix=prefix, cache=cache)
    454 
    455 # TODO: inherit all the data structure from CombinatorialFreeModule(base_ring, self._lattice)
     510    return cache_wcr(ct, base_ring=base_ring, prefix=prefix, cache=cache, style=style)
    456511
    457512class WeylCharacterRing_class(Algebra):
    458     def __init__(self, ct, base_ring, prefix, cache):
     513    def __init__(self, ct, base_ring, prefix, cache, style):
    459514        """
    460515        EXAMPLES::
    461516       
     
    466521        sage.structure.parent_base.ParentWithBase.__init__(self, base_ring)
    467522
    468523        self._cartan_type = ct
     524        self._rank = ct.rank()
    469525        self._base_ring = base_ring
    470         self._lattice = RootSystem(self._cartan_type).ambient_space()
    471         self._origin = self._lattice.zero()
     526        self._space = RootSystem(self._cartan_type).ambient_space()
     527        self._origin = self._space.zero()
    472528        if prefix == None:
    473             prefix = ct[0]+str(ct[1])
     529            if ct.is_irreducible():
     530                prefix = ct[0]+str(ct[1])
     531            else:
     532                prefix = ct.__repr__()
    474533        self._prefix = prefix
    475         alpha = self._lattice.simple_roots()
    476         Lambda = self._lattice.fundamental_weights()
    477         # FIXME: indexing of fundamental weights
    478         self._ip = [Lambda[i].inner_product(alpha[i])
    479                     for i in ct.index_set()]
     534        self._style = style
     535        alpha = self._space.simple_roots()
     536        Lambda = self._space.fundamental_weights()
    480537        self._cache = cache
    481538        if cache:
    482539            self._irreducibles={}
    483540
    484 
    485541    def __call__(self, *args):
    486542        """
    487543        Coerces the element into the ring. You may pass a vector in the
    488         ambient lattice, an element of the base_ring, or an argument list
     544        ambient space, an element of the base_ring, or an argument list
    489545        of integers (or half-integers for the spin types) which are the
    490         components of a vector in the ambient lattice.
     546        components of a vector in the ambient space.
    491547       
    492548        INPUT:
    493549       
     
    499555       
    500556        EXAMPLES::
    501557       
    502             sage: A2 = WeylCharacterRing(['A',2])
     558            sage: A2 = WeylCharacterRing("A2")
    503559            sage: [A2(x) for x in [-2,-1,0,1,2]]
    504560            [-2*A2(0,0,0), -A2(0,0,0), 0, A2(0,0,0), 2*A2(0,0,0)]
    505561            sage: [A2(2,1,0), A2([2,1,0]), A2(2,1,0)== A2([2,1,0])]
     
    520576        else:
    521577            x = args
    522578
    523         if x == 0:
     579        if x == 0 and not x in self._space:
    524580            return WeylCharacter(self, {}, {})
    525581       
    526582        if x in ZZ:
    527583            hdict = {self._origin: x}
    528584            return WeylCharacter(self, hdict, hdict)
    529585       
     586        if self._style == "coroots" and all(xv in ZZ for xv in x):
     587            x = sum(x[i]*list(self.fundamental_weights())[i] for i in range(self._rank))
     588
    530589        if is_Element(x):
    531590            P = x.parent()
    532591            if P is self:
     
    537596                hdict = {self._origin: x}
    538597                return WeylCharacter(self, hdict, hdict)
    539598
    540         x = self._lattice(x)
    541    
    542         alphacheck = self._lattice.simple_coroots()
    543         vp = [x.inner_product(alphacheck[i])
    544               for i in self._cartan_type.index_set()]
     599        x = self._space(x)
     600
     601        # if style == "coroots" and type == 'A' subtract a power of det to put self in SL(r+1,CC)
     602        if self._style == "coroots":
     603            x = self.coerce_to_sl(x)
     604
     605        alphacheck = self._space.simple_coroots()
     606        vp = [x.inner_product(alphacheck[i]) for i in self._cartan_type.index_set()]
     607       
    545608        if not all(v in ZZ for v in vp):
    546609            raise ValueError, "not in weight lattice"
    547610        if not all(v >= 0 for v in vp):
     
    549612        if self._cache and x in self._irreducibles:
    550613            return self._irreducibles[x]
    551614        hdict = {x: 1}
    552         mdict = irreducible_character_freudenthal(x, self._lattice)
     615        mdict = irreducible_character_freudenthal(x, self._space)
    553616        ret = WeylCharacter(self, hdict, mdict)
    554617        if self._cache:
    555618            self._irreducibles[x] = ret
    556619        return ret
    557620
     621    def coerce_to_sl(self, x):
     622        """
     623        For type ['A',r], this coerces an element of the ambient space into SL(r+1,CC)
     624        by subtracting a (possibly fractional) power of the determinant.
     625        """
     626        if self._cartan_type.is_irreducible():
     627            if self._cartan_type[0] == 'A':
     628                x = x - self._space.det(sum(x.to_vector())/(self._rank+1))
     629        else:
     630            xv = x.to_vector()
     631            shifts = self._cartan_type._shifts
     632            types = self._cartan_type.component_types()
     633            for i in range(len(types)):
     634                if self._cartan_type.component_types()[i][0] == 'A':
     635                    s = self._space.ambient_spaces()[i].det(sum(xv[shifts[i]:shifts[i+1]])/(types[i][1]+1))
     636                    x = x - self._space.inject_weights(i, s)
     637        return x
     638
    558639    def __repr__(self):
    559640        """
    560641        EXAMPLES::
    561642       
    562             sage: WeylCharacterRing(['A',3])
    563             The Weyl Character Ring of Type [A,3] with Integer Ring coefficients
     643            sage: WeylCharacterRing("A3")
     644            The Weyl Character Ring of Type ['A', 3] with Integer Ring coefficients
    564645        """
    565         return "The Weyl Character Ring of Type [%s,%d] with %s coefficients"%(self._cartan_type[0], self._cartan_type[1], self._base_ring.__repr__())
     646        return "The Weyl Character Ring of Type %s with %s coefficients"%(self._cartan_type.__repr__(), self._base_ring.__repr__())
    566647
    567648    def __cmp__(self, x):
    568649        """
     
    599680        """
    600681        return self._cartan_type
    601682
     683    def fundamental_weights(self):
     684        """
     685        Returns the fundamental weights.
     686
     687        EXAMPLES::
     688
     689            sage: WeylCharacterRing("G2").fundamental_weights()
     690            Finite family {1: (1, 0, -1), 2: (2, -1, -1)}
     691        """
     692        return self._space.fundamental_weights()
     693
     694    def simple_roots(self):
     695        """
     696        Returns the simple roots.
     697
     698        EXAMPLES::
     699
     700            sage: WeylCharacterRing("G2").simple_roots()
     701            Finite family {1: (0, 1, -1), 2: (1, -2, 1)}
     702        """
     703        return self._space.simple_roots()
     704
     705    def simple_coroots(self):
     706        """
     707        Returns the simple coroots.
     708
     709        EXAMPLES::
     710
     711            sage: WeylCharacterRing("G2").simple_roots()
     712            Finite family {1: (0, 1, -1), 2: (1, -2, 1)}
     713        """
     714        return self._space.simple_coroots()
     715
     716    def positive_roots(self):
     717        """
     718        Returns the positive roots.
     719
     720        EXAMPLES::
     721
     722            sage: WeylCharacterRing("G2").positive_roots()
     723            [(0, 1, -1), (1, -2, 1), (1, -1, 0), (1, 0, -1), (1, 1, -2), (2, -1, -1)]
     724        """
     725        return self._space.positive_roots()
     726
     727    def rank(self):
     728        """
     729        Returns the rank.
     730
     731        EXAMPLES::
     732
     733            sage: WeylCharacterRing("G2").rank()
     734            2
     735        """
     736        return self._rank
     737
    602738    def _coerce_impl(self, x):
    603739        """
    604740        Coercion from the base ring.
     
    615751            return self.__call__(x)
    616752        raise TypeError, "no canonical coercion of x"
    617753
    618     # FIXME: should be something like weight_lattice_realization?
    619     def lattice(self):
     754    def space(self):
    620755        """
    621         Returns the weight lattice associated to self.
     756        Returns the weight space associated to self.
    622757       
    623758        EXAMPLES::
    624759       
    625             sage: WeylCharacterRing(['E',8]).lattice()
     760            sage: WeylCharacterRing(['E',8]).space()
    626761            Ambient space of the Root system of type ['E', 8]
    627762        """
    628         return self._lattice
     763        return self._space
    629764
    630765    def char_from_weights(self, mdict):
    631766        """
     
    644779        hdict = {}
    645780        ddict = mdict.copy()
    646781        while not ddict == {}:
    647             highest = max((x.inner_product(self._lattice.rho()),x) for x in ddict)[1]
     782            highest = max((x.inner_product(self._space.rho()),x) for x in ddict)[1]
    648783            if not highest.is_dominant():
    649784                raise ValueError, "multiplicity dictionary may not be Weyl group invariant"
    650785            if self._cache and highest in self._irreducibles:
    651786                sdict = self._irreducibles[highest]._mdict
    652787            else:
    653                 sdict = irreducible_character_freudenthal(highest, self._lattice)
     788                sdict = irreducible_character_freudenthal(highest, self._space)
    654789            if self._cache and not highest in self._irreducibles:
    655790                self._irreducibles[highest] = WeylCharacter(self, {highest:1}, sdict)
    656791            c = ddict[highest]
     
    675810       
    676811        EXAMPLES::
    677812       
    678             sage: A2 = WeylCharacterRing(['A',2])
    679             sage: A2.irr_repr([2,1,0])
    680             'A2(2,1,0)'
     813            sage: B3 = WeylCharacterRing("B3")
     814            sage: [B3.irr_repr(v) for v in B3.fundamental_weights()]
     815            ['B3(1,0,0)', 'B3(1,1,0)', 'B3(1/2,1/2,1/2)']
     816            sage: B3 = WeylCharacterRing("B3", style="coroots")
     817            sage: [B3.irr_repr(v) for v in B3.fundamental_weights()]
     818            ['B3(1,0,0)', 'B3(0,1,0)', 'B3(0,0,1)']
    681819        """
    682         hstring = str(hwv[0])
    683         for i in range(1,self._lattice.n):
    684             hstring=hstring+","+str(hwv[i])
     820        if self._style == "lattice":
     821            vec = hwv.to_vector()
     822        elif self._style == "coroots":
     823            vec = [hwv.inner_product(x) for x in self.simple_coroots()]
     824        else:
     825            raise ValueError, "unknown style"
     826        hstring = str(vec[0])
     827        for i in range(1,len(vec)):
     828            hstring=hstring+","+str(vec[i])
    685829        return self._prefix+"("+hstring+")"
    686830
    687831cache_wcr = Cache(WeylCharacterRing_class)
     
    704848
    705849    - ``hwv`` - a dominant weight in a weight lattice.
    706850
    707     - ``L`` - the ambient lattice
     851    - ``L`` - the ambient space
    708852    """
    709853
    710854    rho = L.rho()
     
    749893    A Branching rule describes the restriction of representations from
    750894    a Lie group or algebra G to a smaller one. See for example, R. C.
    751895    King, Branching rules for classical Lie groups using tensor and
    752     spinor methods. J. Phys. A 8 (1975), 429-449 or Howe, Tan and
     896    spinor methods. J. Phys. A 8 (1975), 429-449, Howe, Tan and
    753897    Willenbring, Stable branching rules for classical symmetric pairs,
    754     Trans. Amer. Math. Soc. 357 (2005), no. 4, 1601-1626.
     898    Trans. Amer. Math. Soc. 357 (2005), no. 4, 1601-1626 and McKay and
     899    Patera, Tables of Dimensions, Indices and Branching Rules for
     900    Representations of Simple Lie Algebras (Marcel Dekker, 1981).
    755901   
    756902    INPUT:
    757903
     
    768914    "automorphic", "symmetric", "extended", "triality" or
    769915    "miscellaneous". The use of these rules will be explained next.
    770916    After the examples we will explain how to write your own branching
    771     rules for cases that we have omitted. (Rules for the exceptional
    772     groups have not yet been coded.)
     917    rules for cases that we have omitted.
    773918   
    774919    To explain the predefined rules we survey the most important
    775920    branching rules. These may be classified into several cases, and
     
    778923    subgroups of Lie groups in Mat. Sbornik N.S. 30(72):349-462
    779924    (1952).
    780925   
    781     We will list these for the cases where the Dynkin diagram of S is
    782     connected. This excludes branching rules such as A3 -> A1 x A1,
    783     which are not yet implemented.
     926    We will list give predefined rules that cover most cases where the
     927    branching rule is to a maximal subgroup. For convenience, we
     928    also give some branching rules to subgroups that are not maximal.
     929    For example, a Levi subgroup may or may not be maximal, but you
     930    can usually branch to it.
    784931   
    785932    LEVI TYPE. These can be read off from the Dynkin diagram. If
    786933    removing a node from the Dynkin diagram produces another Dynkin
     
    788935    smaller diagram be connected. For these rules use the option
    789936    rule="levi"::
    790937   
    791        ['A',r] -> ['A',r-1]
    792        ['B',r] -> ['A',r-1]
    793        ['B',r] -> ['B',r-1]
    794        ['C',r] -> ['A',r-1]
    795        ['C',r] -> ['C',r-1]
    796        ['D',r] -> ['A',r-1]
    797        ['D',r] -> ['D',r-1]
    798        ['E',r] -> ['A',r-1] r = 6,7,8 (not implemented yet)
    799        ['E',r] -> ['D',r-1] r = 6,7,8 (not implemented yet)
    800        ['E',r] -> ['E',r-1] r = 6,7 (not implemented yet)
    801        ['F',4] -> ['B',3] (not implemented yet)
    802        ['F',4] -> ['C',3] (not implemented yet)
    803        ['G',2] -> ['A',1] (short root) (not implemented yet)
     938       ['A',r] => ['A',r-1]
     939       ['B',r] => ['A',r-1]
     940       ['B',r] => ['B',r-1]
     941       ['C',r] => ['A',r-1]
     942       ['C',r] => ['C',r-1]
     943       ['D',r] => ['A',r-1]
     944       ['D',r] => ['D',r-1]
     945       ['E',r] => ['A',r-1] r = 6,7,8 (not implemented yet)
     946       ['E',r] => ['D',r-1] r = 6,7,8 (not implemented yet)
     947       ['E',r] => ['E',r-1] r = 6,7 (not implemented yet)
     948       F4 => B3
     949       F4 => C3
     950       G2 => A1 (short root)
    804951   
    805     The other Levi branching rule from `G_2` -> `A_1` corresponding to the
    806     long root is available by first branching `G_2` -> `A_2` then branching to
    807     A1.
     952    The other Levi branching rule from G2 => A1 corresponding to the
     953    long root is available by first branching G_2 => A_2 then A2 => A1.
    808954   
    809955    AUTOMORPHIC TYPE. If the Dynkin diagram has a symmetry, then there
    810956    is an automorphism that is a special case of a branching rule.
    811     There is also an exotic"triality" automorphism of D4 having order
    812     3. Use rule="automorphic" or rule="triality"
     957    There is also an exotic "triality" automorphism of D4 having order
     958    3. Use rule="automorphic" or (for D4) rule="triality"
    813959   
    814     ['A',r] - ['A',r] ['D',r] - ['D',r] ['E',6] - ['E',6] (not
    815     implemented yet)
     960    ['A',r] => ['A',r]
     961    ['D',r] => ['D',r]
     962    E6 => E6 (not implemented yet)
    816963   
    817     SYMMETRIC TYPE. Related to the automorphic type, when the Dynkin
    818     diagram has a symmetry there is a branching rule to the subalgebra
    819     (or subgroup) of invariants under the automorphism. Use
    820     rule="symmetric".
     964    SYMMETRIC TYPE. Related to the automorphic type, when either
     965    the Dynkin diagram or the extended diagram has a symmetry
     966    there is a branching rule to the subalgebra (or subgroup) of
     967    invariants under the automorphism. Use rule="symmetric".
     968    The last branching rule, D4=>G2 is not to a maximal subgroup
     969    since D4=>B3=>G2, but it is included for convenience.
    821970   
    822     ['A',2r+1] - ['B',r] ['A',2r] - ['C',r] ['D',r] - ['B',r-1] ['E',6]
    823     - ['F',4] (not implemented yet) ['D',4] - ['G',2] (not implemented
    824     yet)
     971    ['A',2r+1] => ['B',r]
     972    ['A',2r] => ['C',r]
     973    ['A',2r] => ['D',r]
     974    ['D',r] => ['B',r-1]
     975    E6 => F4
     976    D4 => G2
    825977   
    826978    EXTENDED TYPE. If removing a node from the extended Dynkin diagram
    827979    results in a Dynkin diagram, then there is a branching rule. Use
    828     rule="extended" for these.
     980    rule="extended" for these. We will also use this classification
     981    for some rules that are not of this type, mainly involving type B,
     982    such as D6 => B3xB3.
    829983   
    830     ['G',2] - ['A',2] (not implemented yet) ['B',r] - ['D',r] ['F',4] -
    831     ['B',4] (not implemented yet) ['E',7] - ['A',7] (not implemented
    832     yet) ['E',8] - ['A',8] (not implemented yet)
     984    G2 => A2
     985    ['B',r] => ['D',r]
     986    F4 => B4
     987    E7 => A7 (not implemented yet)
     988    E8 => A8 (not implemented yet)
    833989   
     990    Here is the extended Dynkin diagram for D6:
     991   
     992        0       6
     993        O       O
     994        |       |
     995        |       |
     996    O---O---O---O---O
     997    1   2   3   4   6
     998
     999    Removing the node 3 results in an embedding D3xD3 -> D6. This
     1000    corresponds to the embedding SO(6)xSO(6) -> SO(12), and is of
     1001    extended type. On the other hand the embedding SO(5)xSO(7)-->SO(12)
     1002    (e.g. B2xB3 -> D6) cannot be explained this way but for
     1003    uniformity is implemented under rule="extended".
     1004
     1005    You can therefore get any branching rule
     1006
     1007    O(n) => O(a)xO(b)xO(c)x ... where n = a+b+c+ ...
     1008    Sp(2n) => Sp(2a)xSp(2b)xSp(2c)x ... where n = a+b+c+ ...
     1009
     1010    where O(a) = ['D',r] (a=2r) or ['B',r] (a=2r+1)
     1011    and Sp(2r)=['C',r] using rule="extended".   
     1012
     1013    TENSOR: The branching rule
     1014
     1015    ['A', rs-1] => ['A',r-1] x ['A',s-1]
     1016
     1017    corresponding to the tensor product homomorphism GL(r) x GL(s) -> GL(rs)
     1018    is implemented using rule="tensor". There are also branching rules
     1019    for types B,C and D. These are:
     1020
     1021    ['B',2rs+r+s] => ['B',r] x ['B',s]
     1022    ['D',2rs+s] => ['B',r] x ['D',s]
     1023    ['D',2rs] => ['D',r] x ['D',s]
     1024    ['D',2rs] => ['C',r] x ['C',s]
     1025    ['C',2rs+s] => ['B',r] x ['C',s]
     1026    ['C',2rs] => ['C',r] x ['D',s].
     1027
     1028    These are not implemented yet though you may obtain them using
     1029    handwritten rules.
     1030
     1031    SYMMETRIC POWER: The k-th symmetric and exterior power homomorphisms
     1032    map GL(n) --> GL(binomial(n+k-1,k)) and GL(binomial(n,k)). The
     1033    corresponding branching rules are not implemented but a special
     1034    case is. The k-th symmetric power homomorphism SL(2) --> GL(k+1)
     1035    has its image inside of SO(2r+1) if k=2r and inside of Sp(2r) if
     1036    k=2r-1. Hence there are branching rules
     1037
     1038    ['B',r] => A1
     1039    ['C',r] => A1
     1040
     1041    and these may be obtained using the rule "symmetric power".
     1042
    8341043    MISCELLANEOUS: Use rule="miscellaneous" for the following rule,
    8351044    which does not fit into the above framework.
    8361045   
    837     ['B',3] - ['G',2] (Not implemented yet.)
     1046    B3 => G2
    8381047   
    8391048    ISOMORPHIC TYPE: Although not usually referred to as a branching
    8401049    rule, the effects of the accidental isomorphisms may be handled
    8411050    using rule="isomorphic"
    8421051   
    843     ['B',2] - ['C',2] ['C',2] - ['B',2] ['A',3] - ['D',3] ['D',3] -
    844     ['A',3]
     1052    B2 => C2
     1053    C2 => B2
     1054    A3 => D3
     1055    D3 => A3
     1056    D2 => A1xA1
     1057    B1 => A1
     1058    C1 => A1
    8451059   
    8461060    EXAMPLES: (Levi type)
    8471061   
    8481062    ::
    8491063   
    850         sage: A2 = WeylCharacterRing(['A',2])
    851         sage: B2 = WeylCharacterRing(['B',2])
    852         sage: C2 = WeylCharacterRing(['C',2])
    853         sage: A3 = WeylCharacterRing(['A',3])
    854         sage: B3 = WeylCharacterRing(['B',3])
    855         sage: C3 = WeylCharacterRing(['C',3])
    856         sage: D3 = WeylCharacterRing(['D',3])
    857         sage: A4 = WeylCharacterRing(['A',4])
    858         sage: D4 = WeylCharacterRing(['D',4])
    859         sage: A5 = WeylCharacterRing(['A',5])
    860         sage: D5 = WeylCharacterRing(['D',5])
    861         sage: [B3(w).branch(A2,rule="levi") for w in B3.lattice().fundamental_weights()]
     1064        sage: A1 = WeylCharacterRing("A1")
     1065        sage: A2 = WeylCharacterRing("A2")
     1066        sage: A3 = WeylCharacterRing("A3")
     1067        sage: A4 = WeylCharacterRing("A4")
     1068        sage: A5 = WeylCharacterRing("A5")
     1069        sage: B2 = WeylCharacterRing("B2")
     1070        sage: B3 = WeylCharacterRing("B3")
     1071        sage: B4 = WeylCharacterRing("B4")
     1072        sage: C2 = WeylCharacterRing("C2")
     1073        sage: C3 = WeylCharacterRing("C3")
     1074        sage: D3 = WeylCharacterRing("D3")
     1075        sage: D4 = WeylCharacterRing("D4")
     1076        sage: D5 = WeylCharacterRing("D5")
     1077        sage: G2 = WeylCharacterRing("G2")
     1078        sage: F4 = WeylCharacterRing("F4") # long time
     1079        sage: [B3(w).branch(A2,rule="levi") for w in B3.fundamental_weights()]
    8621080        [A2(0,0,-1) + A2(0,0,0) + A2(1,0,0),
    8631081         A2(0,-1,-1) + A2(0,0,-1) + A2(0,0,0) + A2(1,0,-1) + A2(1,0,0) + A2(1,1,0),
    8641082         A2(-1/2,-1/2,-1/2) + A2(1/2,-1/2,-1/2) + A2(1/2,1/2,-1/2) + A2(1/2,1/2,1/2)]
     
    8741092   
    8751093    ::
    8761094   
    877         sage: [C3(w).branch(A2,rule="levi") for w in C3.lattice().fundamental_weights()]
     1095        sage: [C3(w).branch(A2,rule="levi") for w in C3.fundamental_weights()]
    8781096        [A2(0,0,-1) + A2(1,0,0),
    8791097         A2(0,-1,-1) + A2(1,0,-1) + A2(1,1,0),
    8801098         A2(-1,-1,-1) + A2(1,-1,-1) + A2(1,1,-1) + A2(1,1,1)]
    881         sage: [D4(w).branch(A3,rule="levi") for w in D4.lattice().fundamental_weights()]
     1099        sage: [D4(w).branch(A3,rule="levi") for w in D4.fundamental_weights()]
    8821100        [A3(0,0,0,-1) + A3(1,0,0,0),
    8831101         A3(0,0,-1,-1) + A3(0,0,0,0) + A3(1,0,0,-1) + A3(1,1,0,0),
    8841102         A3(1/2,-1/2,-1/2,-1/2) + A3(1/2,1/2,1/2,-1/2),
    8851103         A3(-1/2,-1/2,-1/2,-1/2) + A3(1/2,1/2,-1/2,-1/2) + A3(1/2,1/2,1/2,1/2)]
    886         sage: [B3(w).branch(B2,rule="levi") for w in B3.lattice().fundamental_weights()]
     1104        sage: [B3(w).branch(B2,rule="levi") for w in B3.fundamental_weights()]
    8871105        [2*B2(0,0) + B2(1,0), B2(0,0) + 2*B2(1,0) + B2(1,1), 2*B2(1/2,1/2)]
    8881106        sage: C3 = WeylCharacterRing(['C',3])
    889         sage: [C3(w).branch(C2,rule="levi") for w in C3.lattice().fundamental_weights()]
     1107        sage: [C3(w).branch(C2,rule="levi") for w in C3.fundamental_weights()]
    8901108        [2*C2(0,0) + C2(1,0),
    8911109         C2(0,0) + 2*C2(1,0) + C2(1,1),
    8921110         C2(1,0) + 2*C2(1,1)]
    893         sage: [D5(w).branch(D4,rule="levi") for w in D5.lattice().fundamental_weights()]
     1111        sage: [D5(w).branch(D4,rule="levi") for w in D5.fundamental_weights()]
    8941112        [2*D4(0,0,0,0) + D4(1,0,0,0),
    8951113         D4(0,0,0,0) + 2*D4(1,0,0,0) + D4(1,1,0,0),
    8961114         D4(1,0,0,0) + 2*D4(1,1,0,0) + D4(1,1,1,0),
    8971115         D4(1/2,1/2,1/2,-1/2) + D4(1/2,1/2,1/2,1/2),
    8981116         D4(1/2,1/2,1/2,-1/2) + D4(1/2,1/2,1/2,1/2)]
     1117        sage: G2(1,0,-1).branch(A1,rule="levi")
     1118         A1(0,-1) + A1(1,-1) + A1(1,0)
     1119        sage: [F4(fw).branch(B3,rule="levi") for fw in F4.fundamental_weights()] # long time
     1120         [B3(0,0,0) + 2*B3(1/2,1/2,1/2) + 2*B3(1,0,0) + B3(1,1,0),
     1121         B3(0,0,0) + 6*B3(1/2,1/2,1/2) + 5*B3(1,0,0) + 7*B3(1,1,0) + 3*B3(1,1,1)
     1122         + 6*B3(3/2,1/2,1/2) + 2*B3(3/2,3/2,1/2) + B3(2,0,0) + 2*B3(2,1,0) + B3(2,1,1),
     1123         3*B3(0,0,0) + 6*B3(1/2,1/2,1/2) + 4*B3(1,0,0) + 3*B3(1,1,0) + B3(1,1,1) + 2*B3(3/2,1/2,1/2),
     1124         3*B3(0,0,0) + 2*B3(1/2,1/2,1/2) + B3(1,0,0)]
     1125        sage: [F4(fw).branch(C3,rule="levi") for fw in F4.fundamental_weights()] # long time
     1126         [3*C3(0,0,0) + 2*C3(1,1,1) + C3(2,0,0),
     1127         3*C3(0,0,0) + 6*C3(1,1,1) + 4*C3(2,0,0) + 2*C3(2,1,0) + 3*C3(2,2,0) + C3(2,2,2) + C3(3,1,0) + 2*C3(3,1,1),
     1128         2*C3(1,0,0) + 3*C3(1,1,0) + C3(2,0,0) + 2*C3(2,1,0) + C3(2,1,1),
     1129         2*C3(1,0,0) + C3(1,1,0)]
     1130        sage: A1xA1 = WeylCharacterRing("A1xA1")
     1131        sage: [A3(hwv).branch(A1xA1,rule="levi") for hwv in A3.fundamental_weights()]
     1132        [A1xA1(0,0,1,0) + A1xA1(1,0,0,0),
     1133         A1xA1(0,0,1,1) + A1xA1(1,0,1,0) + A1xA1(1,1,0,0),
     1134         A1xA1(1,0,1,1) + A1xA1(1,1,1,0)]
     1135        sage: A1xB1=WeylCharacterRing("A1xB1",style="coroots")
     1136        sage: [B3(x).branch(A1xB1,rule="levi") for x in B3.fundamental_weights()]
     1137        [A1xB1(0,2) + 2*A1xB1(1,0),
     1138         3*A1xB1(0,0) + A1xB1(0,2) + 2*A1xB1(1,2) + A1xB1(2,0),
     1139         2*A1xB1(0,1) + A1xB1(1,1)]
    8991140   
    9001141    EXAMPLES: (Automorphic type, including D4 triality)
    9011142   
    9021143    ::
    9031144   
    904         sage: [A3(chi).branch(A3,rule="automorphic") for chi in A3.lattice().fundamental_weights()]
     1145        sage: [A3(chi).branch(A3,rule="automorphic") for chi in A3.fundamental_weights()]
    9051146        [A3(0,0,0,-1), A3(0,0,-1,-1), A3(0,-1,-1,-1)]
    906         sage: [D4(chi).branch(D4,rule="automorphic") for chi in D4.lattice().fundamental_weights()]
     1147        sage: [D4(chi).branch(D4,rule="automorphic") for chi in D4.fundamental_weights()]
    9071148        [D4(1,0,0,0), D4(1,1,0,0), D4(1/2,1/2,1/2,1/2), D4(1/2,1/2,1/2,-1/2)]
    908         sage: [D4(chi).branch(D4,rule="triality") for chi in D4.lattice().fundamental_weights()]
     1149        sage: [D4(chi).branch(D4,rule="triality") for chi in D4.fundamental_weights()]
    9091150        [D4(1/2,1/2,1/2,-1/2), D4(1,1,0,0), D4(1/2,1/2,1/2,1/2), D4(1,0,0,0)]
    9101151   
    9111152    EXAMPLES: (Symmetric type)
     
    9141155   
    9151156        sage: [w.branch(B2,rule="symmetric") for w in [A4(1,0,0,0,0),A4(1,1,0,0,0),A4(1,1,1,0,0),A4(2,0,0,0,0)]]
    9161157        [B2(1,0), B2(1,1), B2(1,1), B2(0,0) + B2(2,0)]
    917         sage: [A5(w).branch(C3,rule="symmetric") for w in A5.lattice().fundamental_weights()]
    918         [C3(1,0,0),
    919          C3(0,0,0) + C3(1,1,0),
    920          C3(1,0,0) + C3(1,1,1),
    921          C3(0,0,0) + C3(1,1,0),
    922          C3(1,0,0)]
    923         sage: [A5(w).branch(D3,rule="symmetric") for w in A5.lattice().fundamental_weights()]
     1158        sage: [A5(w).branch(C3,rule="symmetric") for w in A5.fundamental_weights()]
     1159        [C3(1,0,0), C3(0,0,0) + C3(1,1,0), C3(1,0,0) + C3(1,1,1), C3(0,0,0) + C3(1,1,0), C3(1,0,0)]
     1160        sage: [A5(w).branch(D3,rule="symmetric") for w in A5.fundamental_weights()]
    9241161        [D3(1,0,0), D3(1,1,0), D3(1,1,-1) + D3(1,1,1), D3(1,1,0), D3(1,0,0)]
    925         sage: [D4(x).branch(B3,rule="symmetric") for x in D4.lattice().fundamental_weights()]
    926         [B3(0,0,0) + B3(1,0,0),
    927          B3(1,0,0) + B3(1,1,0),
    928          B3(1/2,1/2,1/2),
    929          B3(1/2,1/2,1/2)]
     1162        sage: [D4(x).branch(B3,rule="symmetric") for x in D4.fundamental_weights()]
     1163        [B3(0,0,0) + B3(1,0,0), B3(1,0,0) + B3(1,1,0), B3(1/2,1/2,1/2), B3(1/2,1/2,1/2)]
     1164        sage: [D4(x).branch(G2,rule="symmetric") for x in D4.fundamental_weights()]
     1165        [G2(0,0,0) + G2(1,0,-1), 2*G2(1,0,-1) + G2(2,-1,-1), G2(0,0,0) + G2(1,0,-1), G2(0,0,0) + G2(1,0,-1)]
     1166        sage: E6=WeylCharacterRing("E6",style="coroots") # long time
     1167        sage: F4=WeylCharacterRing("F4",style="coroots") # long time
     1168        sage: [E6(fw).branch(F4,rule="symmetric") for fw in E6.fundamental_weights()] # long time
     1169        [F4(0,0,0,0) + F4(0,0,0,1),
     1170         F4(0,0,0,1) + F4(1,0,0,0),
     1171         F4(0,0,0,1) + F4(1,0,0,0) + F4(0,0,1,0),
     1172         F4(1,0,0,0) + 2*F4(0,0,1,0) + F4(1,0,0,1) + F4(0,1,0,0),
     1173         F4(0,0,0,1) + F4(1,0,0,0) + F4(0,0,1,0),
     1174         F4(0,0,0,0) + F4(0,0,0,1)]
    9301175   
    9311176    EXAMPLES: (Extended type)
    9321177   
    9331178    ::
    9341179   
    935         sage: [B3(x).branch(D3,rule="extended") for x in B3.lattice().fundamental_weights()]
     1180        sage: [B3(x).branch(D3,rule="extended") for x in B3.fundamental_weights()]
    9361181        [D3(0,0,0) + D3(1,0,0),
    9371182         D3(1,0,0) + D3(1,1,0),
    9381183         D3(1/2,1/2,-1/2) + D3(1/2,1/2,1/2)]
    939    
     1184        sage: [G2(w).branch(A2, rule="extended") for w in G2.fundamental_weights()]
     1185        [A2(0,0,0) + A2(1/3,1/3,-2/3) + A2(2/3,-1/3,-1/3),
     1186         A2(1/3,1/3,-2/3) + A2(2/3,-1/3,-1/3) + A2(1,0,-1)]
     1187        sage: [F4(fw).branch(B4,rule="extended") for fw in F4.fundamental_weights()] # long time
     1188        [B4(1/2,1/2,1/2,1/2) + B4(1,1,0,0),
     1189         B4(1,1,0,0) + B4(1,1,1,0) + B4(3/2,1/2,1/2,1/2) + B4(3/2,3/2,1/2,1/2) + B4(2,1,1,0),
     1190         B4(1/2,1/2,1/2,1/2) + B4(1,0,0,0) + B4(1,1,0,0) + B4(1,1,1,0) + B4(3/2,1/2,1/2,1/2),
     1191         B4(0,0,0,0) + B4(1/2,1/2,1/2,1/2) + B4(1,0,0,0)]
     1192        sage: G2 = WeylCharacterRing("G2", style="coroots")
     1193        sage: A1xA1 = WeylCharacterRing("A1xA1", style="coroots")
     1194        sage: G2(1,0).branch(A1xA1, rule="extended")
     1195         A1xA1(1,1) + A1xA1(2,0)
     1196        sage: G2(0,1).branch(A1xA1, rule="extended")
     1197         A1xA1(0,2) + A1xA1(2,0) + A1xA1(3,1)
     1198
     1199    For example we can get the branching rule D4 => A1xA1xA1xA1 by remembering
     1200    that A1xA1 = D2.
     1201
     1202        sage: D4=WeylCharacterRing("D4",style="coroots")
     1203        sage: D2xD2=WeylCharacterRing("D2xD2",style="coroots")
     1204        sage: [D4(fw).branch(D2xD2, rule="extended") for fw in D4.fundamental_weights()]
     1205        [D2xD2(0,0,1,1) + D2xD2(1,1,0,0),
     1206         D2xD2(0,0,2,0) + D2xD2(0,0,0,2) + D2xD2(2,0,0,0) + D2xD2(1,1,1,1) + D2xD2(0,2,0,0),
     1207         D2xD2(1,0,0,1) + D2xD2(0,1,1,0),
     1208         D2xD2(1,0,1,0) + D2xD2(0,1,0,1)]
     1209
     1210
     1211    EXAMPLES: (Tensor type)
     1212
     1213        sage: A5=WeylCharacterRing("A5", style="coroots")
     1214        sage: A2xA1=WeylCharacterRing("A2xA1", style="coroots")
     1215        sage: [A5(hwv).branch(A2xA1, rule="tensor") for hwv in A5.fundamental_weights()]
     1216        [A2xA1(1,0,1),
     1217         A2xA1(0,1,2) + A2xA1(2,0,0),
     1218         A2xA1(0,0,3) + A2xA1(1,1,1),
     1219         A2xA1(1,0,2) + A2xA1(0,2,0),
     1220         A2xA1(0,1,1)]
     1221
     1222    Although tensor products for the classical types are not implemented
     1223    as hard-coded rules, you may still write your own rule for any given
     1224    case. For example the tensor product homomorphism SO(3)xSO(3)-->SO(9)
     1225    gives a branching rule B4=>B1xB1 which may be computed as follows:
     1226
     1227        sage: B4=WeylCharacterRing("B4",style="coroots")
     1228        sage: B1xB1=WeylCharacterRing("B1xB1",style="coroots")
     1229        sage: [B4(hwv).branch(B1xB1, rule=lambda x : [x[0]-x[2]+x[3],x[0]+x[1]+x[2]]) for hwv in B4.fundamental_weights()]
     1230        [B1xB1(2,2),
     1231         B1xB1(0,2) + B1xB1(2,0) + B1xB1(2,4) + B1xB1(4,2),
     1232         B1xB1(0,2) + B1xB1(0,6) + B1xB1(2,0) + B1xB1(2,2) + B1xB1(2,4) + B1xB1(4,2) + B1xB1(4,4) + B1xB1(6,0),
     1233         B1xB1(1,3) + B1xB1(3,1)]
     1234
     1235    EXAMPLES: (Symmetric Power)
     1236
     1237        sage: A1=WeylCharacterRing("A1",style="coroots")
     1238        sage: B3=WeylCharacterRing("B3",style="coroots")
     1239        sage: C3=WeylCharacterRing("C3",style="coroots")
     1240        sage: [B3(fw).branch(A1,rule="symmetric_power") for fw in B3.fundamental_weights()]
     1241        [A1(6), A1(2) + A1(6) + A1(10), A1(0) + A1(6)]
     1242        sage: [C3(fw).branch(A1,rule="symmetric_power") for fw in C3.fundamental_weights()]
     1243        [A1(5), A1(4) + A1(8), A1(3) + A1(9)]
     1244
     1245    EXAMPLES: (Miscellaneous type)
     1246
     1247    ::
     1248
     1249        sage: G2 = WeylCharacterRing("G2")
     1250        sage: [fw1, fw2, fw3] = B3.fundamental_weights()
     1251        sage: B3(fw1+fw3).branch(G2, rule="miscellaneous")
     1252        G2(1,0,-1) + G2(2,-1,-1) + G2(2,0,-2)
     1253
    9401254    EXAMPLES: (Isomorphic type)
    9411255   
    9421256    ::
    9431257   
    944         sage: [B2(x).branch(C2, rule="isomorphic") for x in B2.lattice().fundamental_weights()]
     1258        sage: [B2(x).branch(C2, rule="isomorphic") for x in B2.fundamental_weights()]
    9451259        [C2(1,1), C2(1,0)]
    946         sage: [C2(x).branch(B2, rule="isomorphic") for x in C2.lattice().fundamental_weights()]
     1260        sage: [C2(x).branch(B2, rule="isomorphic") for x in C2.fundamental_weights()]
    9471261        [B2(1/2,1/2), B2(1,0)]
    948         sage: [A3(x).branch(D3,rule="isomorphic") for x in A3.lattice().fundamental_weights()]
     1262        sage: [A3(x).branch(D3,rule="isomorphic") for x in A3.fundamental_weights()]
    9491263        [D3(1/2,1/2,1/2), D3(1,0,0), D3(1/2,1/2,-1/2)]
    950         sage: [D3(x).branch(A3,rule="isomorphic") for x in D3.lattice().fundamental_weights()]
     1264        sage: [D3(x).branch(A3,rule="isomorphic") for x in D3.fundamental_weights()]
    9511265        [A3(1/2,1/2,-1/2,-1/2), A3(1/4,1/4,1/4,-3/4), A3(3/4,-1/4,-1/4,-1/4)]
    9521266   
    9531267    Here A3(x,y,z,w) can be understood as a representation of SL(4).
     
    9611275    an isomorphism SL(4) -> Spin(6). Conversely, there are two
    9621276    isomorphisms SO(6) -> SL(4), of which we've selected one.
    9631277   
    964     You may also write your own rules. We may arrange a Cartan
    965     subalgebra U of H to be contained in a Cartan subalgebra T of G.
    966     This embedding must be chosen in a particular way - the restriction
    967     of the positive Weyl chamber in G.lattice() must be contained in
    968     the positive Weyl chamber in H.lattice(). The RULE is the adjoint
    969     of this embedding U - T, which is a mapping from the dual space of
    970     T, which is the weight space of G, to the weight space of H.
    971    
     1278    In cases like this you might prefer style="coroots".
     1279
     1280        sage: A3 = WeylCharacterRing("A3",style="coroots")
     1281        sage: D3 = WeylCharacterRing("D3",style="coroots")
     1282        sage: [D3(fw) for fw in D3.fundamental_weights()]
     1283        [D3(1,0,0), D3(0,1,0), D3(0,0,1)]
     1284        sage: [D3(fw).branch(A3,rule="isomorphic") for fw in D3.fundamental_weights()]
     1285        [A3(0,1,0), A3(0,0,1), A3(1,0,0)]
     1286        sage: D2 = WeylCharacterRing("D2", style="coroots")
     1287        sage: A1xA1 = WeylCharacterRing("A1xA1", style="coroots")
     1288        sage: [D2(fw).branch(A1xA1,rule="isomorphic") for fw in D2.fundamental_weights()]
     1289        [A1xA1(1,0), A1xA1(0,1)]
     1290
     1291    BRANCHING FROM A REDUCIBLE ROOT SYSTEM
     1292
     1293    If you are branching from a reducible root system, the rule is
     1294    a list of rules, one for each component type in the root system.
     1295    The rules in the list are given in pairs [type, rule], where
     1296    type is the root system to be branched to, and rule is the
     1297    branching rule.
     1298
     1299        sage: D4 = WeylCharacterRing("D4",style="coroots")
     1300        sage: D2xD2 = WeylCharacterRing("D2xD2",style="coroots")
     1301        sage: A1xA1xA1xA1 = WeylCharacterRing("A1xA1xA1xA1",style="coroots")
     1302        sage: rr = [["A1xA1","isomorphic"],["A1xA1","isomorphic"]]
     1303        sage: [D4(fw) for fw in D4.fundamental_weights()]
     1304        [D4(1,0,0,0), D4(0,1,0,0), D4(0,0,1,0), D4(0,0,0,1)]
     1305        sage: [D4(fw).branch(D2xD2,rule="extended").branch(A1xA1xA1xA1,rule=rr) for fw in D4.fundamental_weights()]
     1306        [A1xA1xA1xA1(0,0,1,1) + A1xA1xA1xA1(1,1,0,0),
     1307         A1xA1xA1xA1(0,0,0,2) + A1xA1xA1xA1(0,0,2,0) + A1xA1xA1xA1(0,2,0,0) + A1xA1xA1xA1(1,1,1,1) + A1xA1xA1xA1(2,0,0,0),
     1308         A1xA1xA1xA1(0,1,1,0) + A1xA1xA1xA1(1,0,0,1),
     1309         A1xA1xA1xA1(0,1,0,1) + A1xA1xA1xA1(1,0,1,0)]
     1310
     1311    WRITING YOUR OWN RULES
     1312
     1313    The rules that are already coded in SAGE are extensive but
     1314    not exhaustive. If you need a rule that is not implemented,
     1315    you may write it yourself.
     1316
     1317    Suppose you want to branch from a group G to a subgroup H.
     1318    Arrange the embedding so that a Cartan subalgebra U of H is
     1319    contained in a Cartan subalgebra T of G. There is thus
     1320    a mapping from the weight spaces Lie(T)* --> Lie(U)*.
     1321    The embedding must be chosen in such a way that the
     1322    restriction of the image of the positive Weyl chamber
     1323    in Lie(T)* is contained in the positive Weyl chamber
     1324    in Lie(U)*.
     1325
     1326    The RULE is this map Lie(T)* = G.space() to Lie(U)* = H.space(),
     1327    which you may implement as a function. As an example, let
     1328    us consider how to implement the branching rule A3 => C2.
     1329    Here H = C2 = Sp(4) embedded as a subgroup in A3 = GL(4). The
     1330    Cartan subalgebra U consists of diagonal matrices with
     1331    eigenvalues u1, u2, -u2, -u1. The C2.space() is the
     1332    two dimensional vector spaces consisting of the linear
     1333    functionals u1 and u2 on U. On the other hand Lie(T) is
     1334    RR^4. A convenient way to see the restriction is to
     1335    think of it as the adjoint of the map [u1,u2] -> [u1,u2,-u2,-u1],
     1336    that is, [x0,x1,x2,x3] -> [x0-x3,x1-x2]. Hence we may
     1337    encode the rule:
     1338
     1339    def rule(x):
     1340        return [x[0]-x[3],x[1]-x[2]]
     1341
     1342    or simply:
     1343
     1344    rule = lambda x : [x[0]-x[3],x[1]-x[2]]
     1345
    9721346    EXAMPLES::
    9731347   
    9741348        sage: A3 = WeylCharacterRing(['A',3])
     
    9791353        sage: A3(1,1,0,0).branch(C2, rule) == C2(0,0) + C2(1,1)
    9801354        True
    9811355    """
    982     r = R._cartan_type[1]
    983     s = S._cartan_type[1]
    984     # Each rule takes a tuple or list and returns a list
    985     if rule == "levi":
    986         if not s == r-1:
    987             raise ValueError, "Rank is wrong"
    988         if R._cartan_type[0] == 'A':
    989             if S._cartan_type[0] == 'A':
    990                 rule = lambda x : list(x)[:r]
    991             else:
    992                 raise ValueError, "Rule not found"
    993         elif R._cartan_type[0] in ['B', 'C', 'D']:
    994             if S._cartan_type[0] == 'A':
    995                 rule = lambda x : x
    996             elif S._cartan_type[0] == R._cartan_type[0]:
    997                 rule = lambda x : list(x)[1:]
    998             else:
    999                 raise ValueError, "Rule not found"
    1000         elif S._cartan_type[0] == 'E' and R._cartan_type[0] in ['A','D','E']:
    1001             raise NotImplementedError, "Exceptional branching rules are yet to be implemented"
    1002         elif S._cartan_type[0] == 'F' and R._cartan_type[0] in ['B','C']:           
    1003             raise NotImplementedError, "Exceptional branching rules are yet to be implemented"
    1004         elif S._cartan_type[0] == 'G' and R._cartan_type[0] == 'A':
    1005             raise NotImplementedError, "Exceptional branching rules are yet to be implemented"
    1006         else:
    1007             raise ValueError, "Rule not found"
    1008     elif rule == "automorphic":
    1009         if not R._cartan_type == S._cartan_type:
    1010             raise ValueError, "Cartan types must agree for automorphic branching rule"
    1011         elif R._cartan_type[0] == 'E' and R._cartan_type[1] == 6:
    1012             raise NotImplementedError, "Exceptional branching rules are yet to be implemented"
    1013         elif R._cartan_type[0] == 'A':
    1014             def rule(x) : y = [-i for i in x]; y.reverse(); return y
    1015         elif R._cartan_type[0] == 'D':
    1016             def rule(x) : x[len(x)-1] = -x[len(x)-1]; return x
    1017         elif R._cartan_type[0] == 'E' and R._cartan_type[1] == 6:
    1018             raise NotImplementedError, "Exceptional branching rules are yet to be implemented"
    1019         else:
    1020             raise ValueError, "No automorphism found"
    1021     elif rule == "triality":
    1022         if not R._cartan_type == S._cartan_type:
    1023             raise ValueError, "Triality is an automorphic type (for D4 only)"
    1024         elif not R._cartan_type[0] == 'D' and r == 4:
    1025             raise ValueError, "Triality is for D4 only"
    1026         else:
    1027             def rule(x):
    1028                 [x1,x2,x3,x4] = x
    1029                 return [(x1+x2+x3+x4)/2,(x1+x2-x3-x4)/2,(x1-x2+x3-x4)/2,(-x1+x2+x3-x4)/2]
    1030     elif rule == "symmetric":
    1031         if R._cartan_type[0] == 'A':
    1032             if (S._cartan_type[0] == 'C' or S._cartan_type[0] == 'D' and r == 2*s-1) or (S._cartan_type[0] == 'B' and r == 2*s):
    1033                 def rule(x):
    1034                     return [x[i]-x[r-i] for i in range(s)]
    1035             else:
    1036                 print S._cartan_type, r, s
    1037                 raise ValueError, "Rule not found"
    1038 
    1039         elif R._cartan_type[0] == 'D' and S._cartan_type[0] == 'B' and s == r-1:
    1040             rule = lambda x : x[:s]
    1041 
    1042         elif R._cartan_type[0] == 'E' and S._cartan_type[0] == '6':
    1043             raise NotImplementedError, "Exceptional branching rules are yet to be implemented"
    1044         else:
    1045             raise ValueError, "Rule not found"
    1046     elif rule == "extended":
    1047         if R._cartan_type[0] == 'B' and S._cartan_type[0] == 'D' and s == r:
    1048             rule = lambda x : x
    1049         elif R._cartan_type[0] == 'G' and S._cartan_type[0] == 'A' and s == r:
    1050             raise NotImplementedError, "Exceptional branching rules are yet to be implemented"
    1051         elif R._cartan_type[0] == 'F' and S._cartan_type[0] == 'B' and s == r:
    1052             raise NotImplementedError, "Exceptional branching rules are yet to be implemented"
    1053         elif R._cartan_type[0] == 'E' and S._cartan_type[0] == 'E' and s == r and r >= 7:
    1054             raise NotImplementedError, "Exceptional branching rules are yet to be implemented"
    1055         else:
    1056             raise ValueError, "Rule not found"
    1057     elif rule == "isomorphic":
    1058         if R._cartan_type[0] == 'B' and S._cartan_type[0] == 'C' and s == 2 and r == 2:
    1059             def rule(x):
    1060                 [x1, x2] = x
    1061                 return [x1+x2, x1-x2]
    1062         elif R._cartan_type[0] == 'C' and S._cartan_type[0] == 'B' and s == 2 and r == 2:
    1063             def rule(x):
    1064                 [x1, x2] = x
    1065                 return [(x1+x2)/2, (x1-x2)/2]
    1066         elif R._cartan_type[0] == 'A' and S._cartan_type[0] == 'D' and s == 3 and r == 3:
    1067             def rule(x):
    1068                 [x1, x2, x3, x4] = x
    1069                 return [(x1+x2-x3-x4)/2, (x1-x2+x3-x4)/2, (x1-x2-x3+x4)/2]
    1070         elif R._cartan_type[0] == 'D' and S._cartan_type[0] == 'A' and s == 3 and r == 3:
    1071             def rule(x):
    1072                 [t1, t2, t3] = x
    1073                 return [(t1+t2+t3)/2, (t1-t2-t3)/2, (-t1+t2-t3)/2, (-t1-t2+t3)/2]
    1074         else:
    1075             raise ValueError, "Rule not found"
    1076 
     1356    if type(rule) == str:
     1357        rule = get_branching_rule(R._cartan_type, S._cartan_type, rule)
     1358    elif R._cartan_type.is_reducible():
     1359        Rtypes = R._cartan_type.component_types()
     1360        Stypes = [CartanType(l[0]) for l in rule]
     1361        rules = [l[1] for l in rule]
     1362        ntypes = len(Rtypes)
     1363        rule_list = [get_branching_rule(Rtypes[i], Stypes[i], rules[i]) for i in range(ntypes)]
     1364        shifts = R._cartan_type._shifts
     1365        def rule(x):
     1366            yl = []
     1367            for i in range(ntypes):
     1368                yl.append(rule_list[i](x[shifts[i]:shifts[i+1]]))
     1369            return flatten(yl)
    10771370    mdict = {}
    10781371    for k in chi._mdict:
    1079         h = S._lattice(rule(list(k.to_vector())))
     1372        if S._style == "coroots":
     1373            h = S.coerce_to_sl(S._space(rule(list(k.to_vector()))))
     1374        else:
     1375            h = S._space(rule(list(k.to_vector())))
    10801376        if h in mdict:
    10811377            mdict[h] += chi._mdict[k]
    10821378        else:
     
    10841380    hdict = S.char_from_weights(mdict)
    10851381    return WeylCharacter(S, hdict, mdict)
    10861382
     1383def get_branching_rule(Rtype, Stype, rule):
     1384    """
     1385    INPUT:
     1386
     1387    - ``R`` - the Weyl Character Ring of G
     1388
     1389    - ``S`` - the Weyl Character Ring of H
     1390
     1391    - ``rule`` - a string describing the branching rule as a map from
     1392      the weight space of S to the weight space of R.
     1393    """
     1394    r = Rtype.rank()
     1395    s = Stype.rank()
     1396    rdim = Rtype.root_system().ambient_space().dimension()
     1397    sdim = Stype.root_system().ambient_space().dimension()
     1398    if rule == "default":
     1399        return lambda x : x
     1400    elif rule == "levi":
     1401        if not s == r-1:
     1402            raise ValueError, "Incompatible ranks"
     1403        if Rtype[0] == 'A':
     1404            if Stype.is_reducible():
     1405                if all(ct[0]=='A' for ct in Stype.component_types()) \
     1406                       and rdim == sdim:
     1407                    return lambda x : x
     1408                else:
     1409                    raise ValueError, "Rule not found"
     1410            elif Stype[0] == 'A':
     1411                return lambda x : list(x)[:r]
     1412            else:
     1413                raise ValueError, "Rule not found"
     1414        elif Rtype[0] in ['B', 'C', 'D']:
     1415            if Stype.is_irreducible():
     1416                if Stype[0] == 'A':
     1417                    return  lambda x : x
     1418                elif Stype[0] == Rtype[0]:
     1419                    return lambda x : list(x)[1:]
     1420            elif Stype.component_types()[-1][0] == Rtype[0] and all(t[0] == 'A' for t in Stype.component_types()[:-1]):
     1421                return lambda x : x
     1422            else:
     1423                raise ValueError, "Rule not found"
     1424        elif Rtype[0] == 'E' and Stype[0] in ['A','D','E']:
     1425            raise NotImplementedError, "Exceptional branching rules are yet to be implemented"
     1426        elif Rtype[0] == 'F' and s == 3:
     1427            if Stype[0] == 'B':
     1428                return lambda x : list(x)[1:]
     1429            elif Stype[0] == 'C':
     1430                return lambda x : [x[1]-x[0],x[2]+x[3],x[2]-x[3]]
     1431            else:
     1432                raise NotImplementedError, "Exceptional branching rules are yet to be implemented"
     1433        elif Rtype[0] == 'G' and Stype[0] == 'A':
     1434            return lambda x : list(x)[1:]
     1435        else:
     1436            raise ValueError, "Rule not found"
     1437    elif rule == "automorphic":
     1438        if not Rtype == Stype:
     1439            raise ValueError, "Cartan types must agree for automorphic branching rule"
     1440        elif Rtype[0] == 'E' and r == 6:
     1441            raise NotImplementedError, "Exceptional branching rules are yet to be implemented"
     1442        elif Rtype[0] == 'A':
     1443            def rule(x) : y = [-i for i in x]; y.reverse(); return y
     1444            return rule
     1445        elif Rtype[0] == 'D':
     1446            def rule(x) : x[len(x)-1] = -x[len(x)-1]; return x
     1447            return rule
     1448        elif Rtype[0] == 'E' and r == 6:
     1449            raise NotImplementedError, "Exceptional branching rules are yet to be implemented"
     1450        else:
     1451            raise ValueError, "No automorphism found"
     1452    elif rule == "triality":
     1453        if not Rtype == Stype:
     1454            raise ValueError, "Triality is an automorphic type (for D4 only)"
     1455        elif not Rtype[0] == 'D' and r == 4:
     1456            raise ValueError, "Triality is for D4 only"
     1457        else:
     1458            return lambda x : [(x[0]+x[1]+x[2]+x[3])/2,(x[0]+x[1]-x[2]-x[3])/2,(x[0]-x[1]+x[2]-x[3])/2,(-x[0]+x[1]+x[2]-x[3])/2]
     1459    elif rule == "symmetric":
     1460        if Rtype[0] == 'A':
     1461            if (Stype[0] == 'C' or Stype[0] == 'D' and r == 2*s-1) or (Stype[0] == 'B' and r == 2*s):
     1462                return lambda x : [x[i]-x[r-i] for i in range(s)]
     1463            else:
     1464                raise ValueError, "Rule not found"
     1465        elif Rtype[0] == 'D' and Stype[0] == 'B' and s == r-1:
     1466            return lambda x : x[:s]
     1467        elif Rtype[0] == 'D' and r == 4 and Stype[0] == 'G':
     1468            return lambda x : [x[0]+x[1], -x[1]+x[2], -x[0]-x[2]]
     1469        elif Rtype[0] == 'E' and Stype[0] == 'F' and r == 6 and s == 4:
     1470            return lambda x : [(x[4]-3*x[5])/2,(x[0]+x[1]+x[2]+x[3])/2,(-x[0]-x[1]+x[2]+x[3])/2,(-x[0]+x[1]-x[2]+x[3])/2]
     1471        else:
     1472            raise ValueError, "Rule not found"
     1473    elif rule == "extended":
     1474        if Stype.is_reducible():
     1475            if Rtype[0] in ['B','D'] and all(t[0] in ['B','D'] for t in Stype.component_types()):
     1476                if Rtype[0] == 'D':
     1477                    rdeg = 2*r
     1478                else:
     1479                    rdeg = 2*r+1
     1480                sdeg = 0
     1481                for t in Stype.component_types():
     1482                    if t[0] == 'D':
     1483                        sdeg += 2*t[1]
     1484                    else:
     1485                        sdeg += 2*t[1]+1
     1486                if rdeg == sdeg:
     1487                    return lambda x : x[:s]
     1488                else:
     1489                    raise ValueError, "Rule not found"
     1490            elif Rtype[0] == 'C'  and s == r:
     1491                if all(t[0] == Rtype[0] for t in Stype.component_types()):
     1492                    return lambda x : x
     1493            elif Rtype[0] == 'G' and s == r:
     1494                if all(t[0] == 'A' and t[1] == 1 for t in Stype.component_types()):
     1495                    return lambda x : [(x[1]-x[2])/2,-(x[1]-x[2])/2, x[0]/2, -x[0]/2]
     1496            else:
     1497                raise ValueError, "Rule not found"
     1498        elif Rtype[0] == 'B' and Stype[0] == 'D' and s == r:
     1499            return lambda x : x
     1500        elif Rtype[0] == 'G' and Stype[0] == 'A' and s == r:
     1501            return lambda x : [(x[0]-x[2])/3, (-x[1]+x[2])/3, (-x[0]+x[1])/3]
     1502        elif Rtype[0] == 'F' and Stype[0] == 'B' and s == r:
     1503            return lambda x : [-x[0], x[1], x[2], x[3]]
     1504        elif Rtype[0] == 'E' and Stype[0] == 'E' and s == r and r >= 7:
     1505            raise NotImplementedError, "Exceptional branching rules are yet to be implemented"
     1506        else:
     1507            raise ValueError, "Rule not found"
     1508    elif rule == "isomorphic":
     1509        if r != s:
     1510            raise ValueError, "Incompatible ranks"
     1511        if Rtype[0] == 'B' and r == 2 and Stype[0] == 'C':
     1512            def rule(x) : [x1, x2] = x; return [x1+x2, x1-x2]
     1513            return rule
     1514        if Rtype[0] == 'B' and r == 1 and Stype[0] == 'A':
     1515            return lambda x : [x[0],-x[0]]
     1516        elif Rtype[0] == 'C' and r == 2 and Stype[0] == 'B':
     1517            def rule(x) : [x1, x2] = x; return [(x1+x2)/2, (x1-x2)/2]
     1518            return rule
     1519        elif Rtype[0] == 'A' and r == 3 and Stype[0] == 'D':
     1520            def rule(x): [x1, x2, x3, x4] = x; return [(x1+x2-x3-x4)/2, (x1-x2+x3-x4)/2, (x1-x2-x3+x4)/2]
     1521            return rule
     1522        elif Rtype[0] == 'D' and r == 2 and Stype.is_reducible() and \
     1523                 all(t[0] == 'A' for t in Stype.component_types()):
     1524            def rule(x): [t1, t2] = x; return [(t1-t2)/2, -(t1-t2)/2, (t1+t2)/2, -(t1+t2)/2]
     1525            return rule
     1526        elif Rtype[0] == 'D' and r == 3 and Stype[0] == 'A':
     1527            def rule(x): [t1, t2, t3] = x; return [(t1+t2+t3)/2, (t1-t2-t3)/2, (-t1+t2-t3)/2, (-t1-t2+t3)/2]
     1528            return rule
     1529        else:
     1530            raise ValueError, "Rule not found"
     1531    elif rule == "tensor":
     1532        if not Stype.is_reducible():
     1533            raise ValueError, "Tensor product requires more than one factor"           
     1534        if len(Stype.component_types()) is not 2:
     1535            raise ValueError, "Not implemented"
     1536        if Rtype[0] == 'A':
     1537            if all(t[0] == 'A' for t in Stype.component_types()):
     1538                [s1,s2] = [Stype.component_types()[i][1]+1 for i in range(2)]       
     1539                if not s1*s2 == r+1:
     1540                    raise ValueError, "Ranks don't agree with tensor product"
     1541                def rule(x):
     1542                    ret = [sum(x[i*s2:(i+1)*s2]) for i in range(s1)]
     1543                    ret.extend([sum(x[s2*j+i] for j in range(s1)) for i in range(s2)])
     1544                    return ret
     1545                return rule
     1546            else:
     1547                raise ValueError, "Rule not found"
     1548        else:
     1549            raise ValueError, "Not implemented"
     1550    elif rule == "symmetric_power":
     1551        if Stype[0] == 'A' and s == 1:
     1552            if Rtype[0] == 'B':
     1553                def rule(x):
     1554                    a = sum((r-i)*x[i] for i in range(r))
     1555                    return [a,-a]
     1556                return rule
     1557            elif Rtype[0] == 'C':
     1558                def rule(x):
     1559                    a = sum((2*r-2*i-1)*x[i] for i in range(r))
     1560                    return [a/2,-a/2]
     1561                return rule
     1562            else:
     1563                raise ValueError, "Rule not found"
     1564        else:
     1565            raise ValueError, "Rule not found"
     1566    elif rule == "miscellaneous":
     1567        if Rtype[0] == 'B' and Stype[0] == 'G' and r == 3:
     1568            return lambda x : [x[0]+x[1], -x[1]+x[2], -x[0]-x[2]]
     1569        else:
     1570            raise ValueError, "Rule not found"
    10871571
    10881572
    10891573class WeightRingElement(AlgebraElement):
     
    11121596        self._mdict = mdict
    11131597        self._parent = A
    11141598        self._prefix = A._prefix
    1115         self._lattice = A._lattice
     1599        self._space = A._space
    11161600
    11171601    def _wt_repr(self, k):
    11181602        """
     
    11261610            a2(1,0,0)
    11271611        """
    11281612        hstring = str(k[0])
    1129         for i in range(1,self._lattice.n):
     1613        for i in range(1,self._space.n):
    11301614            hstring = hstring+","+str(k[i])
    11311615        return self._prefix+"("+hstring+")"
    11321616
     
    11361620       
    11371621            sage: B3 = WeylCharacterRing(['B',3])
    11381622            sage: b3 = WeightRing(B3)
    1139             sage: fw = b3.lattice().fundamental_weights()
     1623            sage: fw = B3.fundamental_weights()
    11401624            sage: b3(fw[3])
    11411625            b3(1/2,1/2,1/2)
    11421626            sage: b3(B3(fw[3]))
     
    11461630        if self._mdict == {}:
    11471631            return "0"
    11481632        v = self._mdict.keys()
    1149         # Just a workaround to keep the same sorting as before when
    1150         # the dictionary was indexed by tuples
    11511633        v.sort(key = lambda v: tuple(v.to_vector()))
    11521634        return repr_lincomb([self._wt_repr(k) for k in v], [self._mdict[k] for k in v])
    11531635
     
    11571639       
    11581640            sage: B3 = WeylCharacterRing(['B',3])
    11591641            sage: b3 = WeightRing(B3)
    1160             sage: fw = [b3(w) for w in b3.lattice().fundamental_weights()]
     1642            sage: fw = [b3(w) for w in B3.fundamental_weights()]
    11611643            sage: sorted(fw)
    11621644            [b3(1/2,1/2,1/2), b3(1,0,0), b3(1,1,0)]
    11631645        """
     
    12841766       
    12851767            sage: G2 = WeylCharacterRing(['G',2])
    12861768            sage: g2 = WeightRing(G2)
    1287             sage: pr = sum(g2(a) for a in g2.lattice().positive_roots())
     1769            sage: pr = sum(g2(a) for a in G2.positive_roots())
    12881770            sage: sorted(pr.mlist())
    12891771            [[(1, -2, 1), 1],  [(1, -1, 0), 1],  [(1, 1, -2), 1],  [(1, 0, -1), 1],  [(2, -1, -1), 1],  [(0, 1, -1), 1]]
    12901772        """
     
    12981780       
    12991781            sage: G2 = WeylCharacterRing(['G',2])
    13001782            sage: g2 = WeightRing(G2)
    1301             sage: L = g2.lattice()
     1783            sage: L = g2.space()
    13021784            sage: [fw1, fw2] = L.fundamental_weights()
    13031785            sage: sum(g2(fw2).weyl_group_action(w) for w in L.weyl_group())
    13041786            2*g2(-2,1,1) + 2*g2(-1,-1,2) + 2*g2(-1,2,-1) + 2*g2(1,-2,1) + 2*g2(1,1,-2) + 2*g2(2,-1,-1)
     
    13151797       
    13161798            sage: A2 = WeylCharacterRing(['A',2])
    13171799            sage: a2 = WeightRing(A2)
    1318             sage: W = a2.lattice().weyl_group()
     1800            sage: W = a2.space().weyl_group()
    13191801            sage: mu = a2(2,1,0)
    13201802            sage: nu = sum(mu.weyl_group_action(w) for w in W)
    13211803            sage: nu
     
    13551837       
    13561838            sage: A2 = WeylCharacterRing(['A',2])
    13571839            sage: a2 = WeightRing(A2)
    1358             sage: wd = prod(a2(x/2)-a2(-x/2) for x in a2.lattice().positive_roots()); wd
     1840            sage: wd = prod(a2(x/2)-a2(-x/2) for x in a2.space().positive_roots()); wd
    13591841            -a2(-1,0,1) + a2(-1,1,0) + a2(0,-1,1) - a2(0,1,-1) - a2(1,-1,0) + a2(1,0,-1)
    13601842            sage: chi = A2([5,3,0]); chi
    13611843            A2(5,3,0)
     
    13661848            2*a2(4,3,1) + a2(4,4,0) + a2(5,0,3) + a2(5,1,2) + a2(5,2,1) + a2(5,3,0)
    13671849            sage: a2(chi)*wd
    13681850            -a2(-1,3,6) + a2(-1,6,3) + a2(3,-1,6) - a2(3,6,-1) - a2(6,-1,3) + a2(6,3,-1)
    1369             sage: sum((-1)^w.length()*a2([6,3,-1]).weyl_group_action(w) for w in a2.lattice().weyl_group())
     1851            sage: sum((-1)^w.length()*a2([6,3,-1]).weyl_group_action(w) for w in a2.space().weyl_group())
    13701852            -a2(-1,3,6) + a2(-1,6,3) + a2(3,-1,6) - a2(3,6,-1) - a2(6,-1,3) + a2(6,3,-1)
    1371             sage: a2(chi)*wd == sum((-1)^w.length()*a2([6,3,-1]).weyl_group_action(w) for w in a2.lattice().weyl_group())
     1853            sage: a2(chi)*wd == sum((-1)^w.length()*a2([6,3,-1]).weyl_group_action(w) for w in a2.space().weyl_group())
    13721854            True
    13731855       
    13741856        In the above example, we create a WeylCharacterRing A2 whose
     
    13851867       
    13861868            sage: R = WeylCharacterRing(['G',2], prefix = "R", base_ring = QQ)
    13871869            sage: S = WeightRing(R, prefix = "S")
    1388             sage: L = S.lattice()
     1870            sage: L = S.space()
    13891871            sage: vc = [sum(S(1/2)*S(f).weyl_group_action(w) for w in L.weyl_group()) for f in L.fundamental_weights()]; vc
    13901872            [S(-1,0,1) + S(-1,1,0) + S(0,-1,1) + S(0,1,-1) + S(1,-1,0) + S(1,0,-1),
    13911873            S(-2,1,1) + S(-1,-1,2) + S(-1,2,-1) + S(1,-2,1) + S(1,1,-2) + S(2,-1,-1)]
     
    14071889            elif self._parent._prefix.islower():
    14081890                prefix = self._parent._prefix.upper()
    14091891            else:
    1410                 prefix = (self._cartan_type[0].lower()+str(self._cartan_type[1]))
     1892                prefix = (self._cartan_type[0].lower()+str(self._rank))
    14111893        self._base_ring = self._parent._base_ring
    1412         self._lattice = self._parent._lattice
     1894        self._space = self._parent._space
    14131895        self._origin = self._parent._origin
    14141896        self._prefix = prefix
    1415         self._ip = self._parent._ip
    14161897
    14171898    def __call__(self, *args):
    14181899        """
     
    14511932                return WeightRingElement(self, x._mdict)
    14521933        except AttributeError:
    14531934            pass
    1454         x = self._lattice(x)
     1935        x = self._space(x)
    14551936        mdict = {x: 1}
    14561937        return WeightRingElement(self, mdict)
    14571938
     
    14621943            sage: P.<q>=QQ[]
    14631944            sage: G2 = WeylCharacterRing(['G',2], base_ring = P)
    14641945            sage: WeightRing(G2)
    1465             The Weight ring attached to The Weyl Character Ring of Type [G,2] with Univariate Polynomial Ring in q over Rational Field coefficients
     1946            The Weight ring attached to The Weyl Character Ring of Type ['G', 2] with Univariate Polynomial Ring in q over Rational Field coefficients
    14661947        """
    14671948        return "The Weight ring attached to %s"%self._parent.__repr__()
    14681949
     
    15192000        """
    15202001        return self._cartan_type
    15212002
    1522     def lattice(self):
     2003    def space(self):
    15232004        """
    1524         Returns the weight lattice realization associated to self.
     2005        Returns the weight space realization associated to self.
    15252006
    15262007        EXAMPLES::
    15272008       
    15282009            sage: E8 = WeylCharacterRing(['E',8])
    15292010            sage: e8 = WeightRing(E8)
    1530             sage: e8.lattice()
     2011            sage: e8.space()
    15312012            Ambient space of the Root system of type ['E', 8]
    15322013        """
    1533         return self._lattice
     2014        return self._space
     2015
     2016    def fundamental_weights(self):
     2017        """
     2018        Returns the fundamental weights.
     2019
     2020        EXAMPLES::
     2021
     2022            sage: WeightRing(WeylCharacterRing("G2")).fundamental_weights()
     2023            Finite family {1: (1, 0, -1), 2: (2, -1, -1)}
     2024        """
     2025        return self._space.fundamental_weights()
     2026
     2027    def simple_roots(self):
     2028        """
     2029        Returns the simple roots.
     2030
     2031        EXAMPLES::
     2032
     2033            sage: WeightRing(WeylCharacterRing("G2")).simple_roots()
     2034            Finite family {1: (0, 1, -1), 2: (1, -2, 1)}
     2035        """
     2036        return self._space.simple_roots()
     2037
     2038    def positive_roots(self):
     2039        """
     2040        Returns the positive roots.
     2041
     2042        EXAMPLES::
     2043
     2044            sage: WeightRing(WeylCharacterRing("G2")).positive_roots()
     2045            [(0, 1, -1), (1, -2, 1), (1, -1, 0), (1, 0, -1), (1, 1, -2), (2, -1, -1)]
     2046        """
     2047        return self._space.positive_roots()
    15342048
    15352049    def wt_repr(self, wt):
    15362050        """
     
    15452059            'g2(1,0,0)'
    15462060        """
    15472061        hstring = str(wt[0])
    1548         for i in range(1,self._lattice.n):
     2062        for i in range(1,self._space.n):
    15492063            hstring=hstring+","+str(wt[i])
    15502064        return self._prefix+"("+hstring+")"
    15512065