The following patch was originally intended to correct a problem with
the weights for type A. The reason for the patch, and the plan of the
patch are described here.

http://groups.google.com/group/sage-combinat-devel/browse_thread/thread/7cdfe075257ba963?hl=en

As it turns out, the patch produces a substantial speedup for
computing the weights for crystals of moderate size. For example,
consider this crystal.

sage: C = CrystalOfTableaux(['A',4],shape=[4,2,2])
sage: C.count()
560

BEFORE THE PATCH:

sage: time [v.weight() for v in C]
CPU times: user 2.66 s, sys: 0.04 s, total: 2.69 s
Wall time: 2.71

AFTER THE PATCH:
sage: CPU times: user 0.79 s, sys: 0.00 s, total: 0.79 s
Wall time: 0.79

Similar speedups are found for the other Cartan types B,C,D and G2.

Note that the original weight code is still in place and will
be called for Crystals that are not Crystals of Tableaux or of
Letters.


diff -r 80b506b8e07c sage/combinat/crystals/letters.py
--- a/sage/combinat/crystals/letters.py	Tue Apr 01 19:18:55 2008 -0700
+++ b/sage/combinat/crystals/letters.py	Mon Apr 07 22:25:42 2008 -0700
@@ -142,7 +142,6 @@ class ClassicalCrystalOfLetters(Classica
         """
         return self._digraph
     
-
     def __contains__(self, x):
         """
         EXAMPLES:
@@ -287,7 +286,13 @@ class Crystal_of_letters_type_A_element(
 
         sage: C.check()
         True
-    """
+
+        sage: [v.weight() for v in CrystalOfLetters(['A',3])]
+        [(1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 0, 0, 1)]
+    """
+    def weight(self):
+        return self._parent.weight_lattice_realization()._term(self.value-1)
+
     def e(self, i):
         r"""
         Returns the action of $e_i$ on self.
@@ -330,7 +335,23 @@ class Crystal_of_letters_type_B_element(
         sage: C = CrystalOfLetters (['B',3])
         sage: C.check()
         True
-    """
+        sage: [v.weight() for v in CrystalOfLetters(['B',3])]
+        [(1, 0, 0),
+         (0, 1, 0),
+         (0, 0, 1),
+         (0, 0, 0),
+         (0, 0, -1),
+         (0, -1, 0),
+         (-1, 0, 0)]
+    """
+    def weight(self):
+        if self.value > 0:
+            return self._parent.weight_lattice_realization()._term(self.value-1)
+        elif self.value < 0:
+            return -self._parent.weight_lattice_realization()._term(-self.value-1)
+        else:
+            return self._parent.weight_lattice_realization()._free_module(0)
+
     def e(self, i):
         r"""
         Returns the action of $e_i$ on self.
@@ -410,8 +431,17 @@ class Crystal_of_letters_type_C_element(
          [False, False, False, False, False, False]]
         sage: C.check()
         True
-   
-    """
+        sage: [v.weight() for v in CrystalOfLetters(['C',3])]
+        [(1, 0, 0), (0, 1, 0), (0, 0, 1), (0, 0, -1), (0, -1, 0), (-1, 0, 0)]
+    """
+    def weight(self):
+        if self.value > 0:
+            return self._parent.weight_lattice_realization()._term(self.value-1)
+        elif self.value < 0:
+            return -self._parent.weight_lattice_realization()._term(-self.value-1)
+        else:
+            return self._parent.weight_lattice_realization()._free_module(0)
+
     def e(self, i):
         r"""
         Returns the action of $e_i$ on self.
@@ -472,7 +502,25 @@ class Crystal_of_letters_type_D_element(
         [1, 2, 3, 4, -4, -3, -2, -1]
         sage: C.check()
         True
-    """
+
+        sage: [v.weight() for v in CrystalOfLetters(['D',4])]
+        [(1, 0, 0, 0),
+         (0, 1, 0, 0),
+         (0, 0, 1, 0),
+         (0, 0, 0, 1),
+         (0, 0, 0, -1),
+         (0, 0, -1, 0),
+         (0, -1, 0, 0),
+         (-1, 0, 0, 0)]
+    """
+    def weight(self):
+        if self.value > 0:
+            return self._parent.weight_lattice_realization()._term(self.value-1)
+        elif self.value < 0:
+            return -self._parent.weight_lattice_realization()._term(-self.value-1)
+        else:
+            return self._parent.weight_lattice_realization()._free_module(0)
+
     def e(self, i):
         r"""
         Returns the action of $e_i$ on self.
@@ -551,7 +599,33 @@ class Crystal_of_letters_type_G_element(
         [1, 2, 3, 0, -3, -2, -1]
         sage: C.check()
         True
-    """
+        sage: [v.weight() for v in CrystalOfLetters(['G',2])]
+        [(-1, 0, 1),
+         (-1, 1, 0),
+         (0, -1, 1),
+         (0, 0, 0),
+         (0, 1, -1),
+         (1, -1, 0),
+         (1, 0, -1)]
+    """
+    def weight(self):
+        if self.value ==1:
+            return self._parent.weight_lattice_realization()._free_module((-1, 0, 1))
+        elif self.value ==2:
+            return self._parent.weight_lattice_realization()._free_module((-1, 1, 0))
+        elif self.value ==3:
+            return self._parent.weight_lattice_realization()._free_module((0, -1, 1))
+        elif self.value ==0:
+            return self._parent.weight_lattice_realization()._free_module((0, 0, 0))
+        elif self.value ==-3:
+            return self._parent.weight_lattice_realization()._free_module((0, 1, -1))
+        elif self.value ==-2:
+            return self._parent.weight_lattice_realization()._free_module((1, -1, 0))
+        elif self.value ==-1:
+            return self._parent.weight_lattice_realization()._free_module((1, 0, -1))
+        else:
+            raise RuntimeError, "G2 crystal of letters element %d not valid"%self.value
+
     def e(self, i):
         r"""
         Returns the action of $e_i$ on self.
diff -r 80b506b8e07c sage/combinat/crystals/tensor_product.py
--- a/sage/combinat/crystals/tensor_product.py	Tue Apr 01 19:18:55 2008 -0700
+++ b/sage/combinat/crystals/tensor_product.py	Mon Apr 07 22:25:42 2008 -0700
@@ -234,7 +234,6 @@ class TensorProductOfCrystals(ClassicalC
             else:
                 self.module_generators = [ self(*x) for x in options['generators']]
 
-
     def __call__(self, *args):
         """
         EXAMPLES:
@@ -271,6 +270,9 @@ class TensorProductOfCrystalsElement(Imm
         k = position[0]
         return self.set_index(k, self[k].e(i))
     
+    def weight(self):
+        return sum(self[j].weight() for j in range(len(self)))
+
     def f(self, i):
         """
         Returns the action of $f_i$ on self.
