.. _SectRDRoot:

.. _roots-coroots-weights:

Roots, Coroots and Weights
==========================

The roots are stored as an indexed set

.. math:: \{@\; \alpha_1,\dots,\alpha_N,\alpha_{N+1},\dots,\alpha_{2N} \; @\},

where :math:`\alpha_1,\dots,\alpha_N` are the positive roots in an order
compatible with height; and :math:`\alpha_{N+1},\dots,\alpha_{2N}` are the
corresponding negative roots (i.e. :math:`\alpha_{i+N}=-\alpha_i`). The simple
roots are :math:`\alpha_1,\dots,\alpha_n` where :math:`n` is the rank.

Many of these functions have an optional argument ``Basis`` which may take one
of the following values

1. ``"Standard"``: the standard basis for the (co)root space. This is the
default.

2. ``"Root"``: the basis of simple (co)roots.

3. ``"Weight"``: the basis of fundamental (co)weights (see
Subsection :ref:`SubsectRDRootWeight` below).

.. _SubsectRDRootAccess:

.. _access:

Accessing Roots and Coroots
---------------------------

.. magma:function:: RootSpace(R)
   :input_types: RootStr
   :output_types: ModTupFld
   :label: RootSpace_RootStr

.. magma:function:: CorootSpace(R)
   :input_types: RootStr
   :output_types: ModTupFld
   :label: CorootSpace_RootStr

   The vector space containing the (co)roots of the root datum :math:`R`,
   i.e. :math:`X\tens{\mathbb{Q}}` (respectively, :math:`Y\tens{\mathbb{Q}}`).

.. magma:function:: FullRootLattice(R)
   :input_types: RootDtm
   :output_types: Lat, Map
   :label: FullRootLattice_RootDtm

.. magma:function:: FullCorootLattice(R)
   :input_types: RootDtm
   :output_types: Lat, Map
   :label: FullCorootLattice_RootDtm

   The lattice containing the (co)roots of the root datum :math:`R`, i.e. :math:`X`
   (respectively, :math:`Y`). An inclusion map into the (co)root space of :math:`R`
   is returned as the second value.

.. magma:function:: RootLattice(R)
   :input_types: RootDtm
   :output_types: Lat, Map
   :label: RootLattice_RootDtm

.. magma:function:: CorootLattice(R)
   :input_types: RootDtm
   :output_types: Lat, Map
   :label: CorootLattice_RootDtm

   The lattice spanned by the (co)roots of the root datum :math:`R`. An inclusion
   map into the (co)root space of :math:`R` is returned as the second value.

.. magma:example:: Example: Rt Lat
   :label: RtLat

   The root space, full root lattice and the root lattice of the standard root
   datum of type :math:`A_2`:

   .. code-block:: magma

      > R := StandardRootDatum("A",2);
      > V := RootSpace(R);
      > FullRootLattice(R);
      Standard Lattice of rank 3 and degree 3
      Mapping from: Standard Lattice of rank 3 and degree 3 to ModTupFld: V
      > RootLattice(R);
      Lattice of rank 2 and degree 3
      Basis:
      ( 1 -1  0)
      ( 0  1 -1)
      Mapping from: Lattice of rank 2 and degree 3 to ModTupFld: V

.. magma:function:: IsRootSpace(V)
   :input_types: ModTupFld
   :output_types: BoolElt
   :label: IsRootSpace_ModTupFld

.. magma:function:: IsCorootSpace(V)
   :input_types: ModTupFld
   :output_types: BoolElt
   :label: IsCorootSpace_ModTupFld

   Return ``true`` if, and only if, :math:`V` is the (co)root space of some root
   datum.

.. magma:function:: IsInRootSpace(v)
   :input_types: ModTupFldElt
   :output_types: BoolElt
   :label: IsInRootSpace_ModTupFldElt

.. magma:function:: IsCorootSpace(v)
   :input_types: ModTupFldElt
   :output_types: BoolElt
   :label: IsCorootSpace_ModTupFldElt

   Return ``true`` if, and only if, :math:`V` is an element of the (co)root space
   of some root datum.

.. magma:function:: RootDatum(V)
   :input_types: ModTupFld
   :output_types: RootDtm
   :label: RootDatum_ModTupFld

   If :math:`V` is the (co)root space of some root datum, this returns the datum.

.. magma:example:: Example: Rt Is Space
   :label: RtIsSpace

   .. code-block:: magma

      > R := RootDatum("a3");
      > V := RootSpace(R);
      > v := V.1;
      > IsRootSpace(V);
      true
      %%a> assert $1;
      > RootDatum(V);
      R: Adjoint root datum of dimension 3 of type A3 
      > IsInRootSpace(v);
      true
      %%a> assert $1;

.. magma:function:: ZeroRootLattice(R)
   :input_types: RootDtm
   :output_types: Lat
   :label: ZeroRootLattice_RootDtm

.. magma:function:: ZeroRootSpace(R)
   :input_types: RootDtm
   :output_types: ModTupFld, Map
   :label: ZeroRootSpace_RootDtm

   For the given root datum :math:`R`, return the lattice :math:`X_0` and the
   vector space :math:`X_0\tens{\mathbb{Q}}`, respectively (see Section
   :ref:`SubsectExtRD`).

.. magma:function:: RelativeRootSpace(R)
   :input_types: RootDtm
   :output_types: ModTupFld, Map
   :label: RelativeRootSpace_RootDtm

   For the given root datum :math:`R`, return the vector space
   :math:`\bar{X} = (X\tens{\mathbb{Q}})/(X_0\tens{\mathbb{Q}})` containing the
   relative roots (see Section :ref:`SubsectExtRD`). The projection
   from :math:`X\tens{\mathbb{Q}}` onto :math:`\bar{X}` is returned as second
   return value.

.. magma:function:: SimpleRoots(R)
   :input_types: RootStr
   :output_types: Mtrx
   :label: SimpleRoots_RootStr

.. magma:function:: SimpleCoroots(R)
   :input_types: RootStr
   :output_types: Mtrx
   :label: SimpleCoroots_RootStr

   The simple (co)roots of the root datum :math:`R` as the rows of a matrix,
   i.e. :math:`A` (respectively, :math:`B`).

.. magma:example:: Example: Basic Operations
   :label: BasicOperations

   .. code-block:: magma

      > R := RootDatum("G2");
      > RootSpace(R);
      Full Vector space of degree 2 over Rational Field
      > FullRootLattice(R);
      Standard Lattice of rank 2 and degree 2
      Mapping from: Standard Lattice of rank 2 and degree 2 to Full Vector space of 
      degree 2 over Rational Field
      > RootLattice(R);
      Standard Lattice of rank 2 and degree 2
      Mapping from: Standard Lattice of rank 2 and degree 2 to Full Vector space of 
      degree 2 over Rational Field
      > CorootSpace(R);
      Full Vector space of degree 2 over Rational Field
      > SimpleRoots(R);
      [1 0]
      [0 1]
      > SimpleCoroots(R);
      [ 2 -3]
      [-1  2]
      > CartanMatrix(R);
      [ 2 -1]
      [-3  2]
      > Rank(R) eq Dimension(R);
      true
      %%a> assert $1;

.. magma:function:: NumberOfPositiveRoots(R)
   :input_types: RootStr
   :output_types: RngIntElt
   :label: NumberOfPositiveRoots_RootStr

.. magma:function:: NumPosRoots(R)
   :input_types: RootStr
   :output_types: RngIntElt
   :label: NumPosRoots_RootStr

   The number of positive roots of the root datum :math:`R`. This is also the
   number of positive coroots. The total number of (co)roots is twice the number of
   positive (co)roots.

.. magma:function:: Roots(R)
   :input_types: RootStr
   :output_types: $\{@@\}$
   :label: Roots_RootStr

.. magma:function:: Coroots(R)
   :input_types: RootStr
   :output_types: $\{@@\}$
   :label: Coroots_RootStr
   :parameters: Basis : MonStgElt : ``Standard"

   The indexed set of (co)roots of the root datum :math:`R`,
   i.e. :math:`\{@\,\alpha_1,\dots\alpha_{2N}\,@\}` (respectively,
   :math:`\{@\,\alpha_1^\star,\dots\alpha_{2N}^\star\,@\}`).

.. magma:function:: PositiveRoots(R)
   :input_types: RootStr
   :output_types: $\{@@\}$
   :label: PositiveRoots_RootStr

.. magma:function:: PositiveCoroots(R)
   :input_types: RootStr
   :output_types: $\{@@\}$
   :label: PositiveCoroots_RootStr
   :parameters: Basis : MonStgElt : ``Standard"

   The indexed set of positive (co)roots of the root datum :math:`R`,
   i.e. :math:`\{@\,\alpha_1,\dots\alpha_N\,@\}` (respectively,
   :math:`\{@\,\alpha_1^\star,\dots\alpha_N^\star\,@\}`).

.. magma:function:: Root(R, r)
   :input_types: RootStr, RngIntElt
   :output_types: $\{@@\}$
   :label: Root_RootStr_RngIntElt

.. magma:function:: Coroot(R, r)
   :input_types: RootStr, RngIntElt
   :output_types: $\{@@\}$
   :label: Coroot_RootStr_RngIntElt
   :parameters: Basis : MonStgElt : ``Standard"

   The :math:`r`\ th (co)root :math:`\alpha_r` (respectively,
   :math:`\alpha_r^\star`) of the root datum :math:`R`.

.. magma:function:: RootPosition(R, v)
   :input_types: RootStr, .
   :output_types: $\{@@\}$
   :label: RootPosition_RootStr

.. magma:function:: CorootPosition(R, v)
   :input_types: RootStr, .
   :output_types: $\{@@\}$
   :label: CorootPosition_RootStr
   :parameters: Basis : MonStgElt : ``Standard"

   If :math:`v` is a (co)root in the root datum :math:`R`, return its index;
   otherwise return 0. These functions will try to coerce :math:`v` into the
   appropriate lattice; :math:`v` should be written with respect to the basis
   specified by the parameter ``Basis``.

.. magma:function:: BasisChange(R,v)
   :input_types: RootStr, Any
   :output_types: SeqEnum
   :label: BasisChange_RootStr_Any
   :parameters: InBasis : MonStgElt : ``Standard"; OutBasis : MonStgElt : ``Standard"; Coroots : BoolElt : \texttt{false}

   Changes the basis of the vector :math:`v` contained in the space spanned by the
   (co)roots of the root datum :math:`R`. The vector :math:`v` is considered as an
   element of the root space by default. If the parameter ``Coroots`` is set to
   ``true``, :math:`v` is considered as an element of the coroot space. The
   optional arguments ``InBasis`` and ``OutBasis`` may take the same values as the
   parameter ``Basis`` as described at the beginning of the current section.

.. magma:example:: Example: Roots Coroots
   :label: RootsCoroots

   .. code-block:: magma

      > R := RootDatum("A3" : Isogeny := 2);
      > Roots(R);
      {@
      \    (1 0 0),
      \    (0 1 0),
      \    (1 0 2),
      \    (1 1 0),
      \    (1 1 2),
      \    (2 1 2),
      \    (-1  0  0),
      \    (0 -1  0),
      \    (-1  0 -2),
      \    (-1 -1  0),
      \    (-1 -1 -2),
      \    (-2 -1 -2)
      @}
      > PositiveCoroots(R);
      {@
      \    (2 -1 -1),
      \    (-1  2  0),
      \    (0 -1  1),
      \    (1  1 -1),
      \    (-1  1  1),
      \    (1 0 0)
      @}
      > #Roots(R) eq 2*NumPosRoots(R);
      true
      %%a> assert $1;
      > Coroot(R, 4);
      (1  1 -1)
      > Coroot(R, 4 : Basis := "Root");
      (1 1 0)
      > CorootPosition(R, [1,1,-1]);
      4
      %%a> assert $1 eq 4;
      > CorootPosition(R, [1,1,0] : Basis := "Root");
      4
      %%a> assert $1 eq 4;
      > BasisChange(R, [1,0,0] : InBasis:="Root");
      (1 0 0)
      > BasisChange(R, [1,0,0] : InBasis:="Root", Coroots);
      ( 2 -1 -1)

.. magma:function:: IsInRootSpace(R,v)
   :input_types: RootDtm, ModTupFldElt
   :output_types: BoolElt
   :label: IsInRootSpace_RootDtm_ModTupFldElt

.. magma:function:: IsInCorootSpace(R,v)
   :input_types: RootDtm, ModTupFldElt
   :output_types: BoolElt
   :label: IsInCorootSpace_RootDtm_ModTupFldElt

Returns ``true`` if and only if the vector :math:`v` is contained in the
(co)root space of the root datum :math:`R`.

.. magma:function:: HighestRoot(R)
   :input_types: RootStr
   :output_types: .
   :label: HighestRoot_RootStr

.. magma:function:: HighestCoroot(R)
   :input_types: RootStr
   :output_types: .
   :label: HighestCoroot_RootStr
   :parameters: Basis : MonStgElt : ``Standard"

   The unique (co)root of greatest height in the irreducible root datum :math:`R`.

.. magma:function:: HighestLongRoot(R)
   :input_types: RootStr
   :output_types: .
   :label: HighestLongRoot_RootStr

.. magma:function:: HighestLongCoroot(R)
   :input_types: RootStr
   :output_types: .
   :label: HighestLongCoroot_RootStr
   :parameters: Basis : MonStgElt : ``Standard"

   The unique long (co)root of greatest height in the irreducible root datum
   :math:`R`.

.. magma:function:: HighestShortRoot(R)
   :input_types: RootStr
   :output_types: .
   :label: HighestShortRoot_RootStr

.. magma:function:: HighestShortCoroot(R)
   :input_types: RootStr
   :output_types: .
   :label: HighestShortCoroot_RootStr
   :parameters: Basis : MonStgElt : ``Standard"

   The unique short (co)root of greatest height in the irreducible root datum
   :math:`R`.

.. magma:example:: Example: Highest Roots
   :label: HighestRoots

   .. code-block:: magma

      > R := RootDatum("G2");
      > HighestRoot(R);
      (3 2)
      > HighestLongRoot(R);
      (3 2)
      > HighestShortRoot(R);
      (2 1)

.. magma:function:: RelativeRoots(R)
   :input_types: RootDtm
   :output_types: SetIndx
   :label: RelativeRoots_RootDtm

.. magma:function:: PositiveRelativeRoots(R)
   :input_types: RootDtm
   :output_types: SetIndx
   :label: PositiveRelativeRoots_RootDtm

.. magma:function:: NegativeRelativeRoots(R)
   :input_types: RootDtm
   :output_types: SetIndx
   :label: NegativeRelativeRoots_RootDtm

.. magma:function:: SimpleRelativeRoots(R)
   :input_types: RootDtm
   :output_types: SetIndx
   :label: SimpleRelativeRoots_RootDtm

   The indexed set of all (resp. positive, negative, simple) relative roots of the
   root datum :math:`R`. Note that the relative roots are returned in the order
   induced by the standard ordering on the (nonrelative) roots of :math:`R`.

.. magma:function:: RelativeRootDatum(R)
   :input_types: RootDtm
   :output_types: RootDtm
   :label: RelativeRootDatum_RootDtm

   The relative root datum of the root datum :math:`R`.

.. magma:function:: GammaOrbitsRepresentatives(R, delta)
   :input_types: RootDtm, RngIntElt
   :output_types: SeqEnum
   :label: GammaOrbitsRepresentatives_RootDtm_RngIntElt

   The preimage of a relative root :math:`\delta` is a disjoint union of
   :math:`\Gamma`-orbits on the set of all roots of the root datum :math:`R`. This
   intrinsic returns a sequence of representatives of these orbits.

.. magma:example:: Example: Two Twisted Esixes
   :label: TwoTwistedEsixes

   We first consider the twisted root datum of type :math:`{}^2E_6`, which is
   quasisplit: now one with distinguished orbits :math:`\{2\}` and :math:`\{4\}`:
   and now the one with distinguished orbits :math:`\{2\}` and :math:`\{1,6\}`,
   which has a non-reduced relative root datum: Finally, the twisted root Datum of
   type :math:`{}^6D_{4,1}`:

   .. code-block:: magma

      > DynkinDiagram(RootDatum("E6"));

      E6    1 - 3 - 4 - 5 - 6
                    |
                    2
      >
      > R := RootDatum("E6" : Twist:=2 ); R;
      R: Twisted adjoint root datum of type 2E6,4
      > OrbitsOnSimples(R);
      [
           GSet{ 2 },
           GSet{ 4 },
           GSet{ 1, 6 },
           GSet{ 3, 5 }
      ]
      > DistinguishedOrbitsOnSimples(R) eq OrbitsOnSimples(R);
      true
      %%a> assert $1;
      > AnisotropicSubdatum(R);
      Twisted toral root datum of dimension 6
      []
      > RR := RelativeRootDatum(R);RR;
      RR: Adjoint root datum of type F4
      > _,pi := RelativeRootSpace(R);
      > DynkinDiagram(RR);

      F4    1 - 2 =>= 4 - 3
      > [ Position(Roots(RR), pi(Root(R,i)) ) : i in [1,6, 3,5, 4, 2]];
      [ 3, 3, 4, 4, 2, 1 ]
      > R := RootDatum("E6" : Twist := <{{2},{4}},2> ); R;
      R: Twisted adjoint root datum of type 2E6,2
      > OrbitsOnSimples(R);
      [
           GSet{ 2 },
           GSet{ 4 },
           GSet{ 1, 6 },
           GSet{ 3, 5 }
      ]
      > DistinguishedOrbitsOnSimples(R);
      [
           GSet{ 2 },
           GSet{ 4 }
      ]
      > AnisotropicSubdatum(R);
      Twisted root datum of type 2(A2 A2)4,0
      [ 1, 3, 5, 6, 7, 11, 37, 39, 41, 42, 43, 47 ]
      > RR := RelativeRootDatum(R);RR;
      RR: Adjoint root datum of type G2
      > DynkinDiagram(RR);

      G2    2 =<= 1
               3
      > _,pi := RelativeRootSpace(R);
      > [ Position(Roots(RR), pi(Root(R,i)) ) : i in [2,4]];
      [ 1, 2 ]
      > R := RootDatum("E6" : Twist := <{{2},{1,6}},2> ); R;
      R: Twisted adjoint root datum of dimension 6 of type 2E6,2
      > OrbitsOnSimples(R);
      [
           GSet{ 2 },
           GSet{ 4 },
           GSet{ 1, 6 },
           GSet{ 3, 5 }
      ]
      > DistinguishedOrbitsOnSimples(R);
      [
           GSet{ 2 },
           GSet{ 1, 6 }
      ]
      > AnisotropicSubdatum(R);
      Twisted root datum of type 2A3,0
      [ 3, 4, 5, 9, 10, 15, 39, 40, 41, 45, 46, 51 ]
      > RR := RelativeRootDatum(R);RR;
      RR: Adjoint root datum of type BC2
      > DynkinDiagram(RR);

      BC2    1 =>= 2
      > _,pi := RelativeRootSpace(R);
      > [ Position(Roots(RR), pi(Root(R,i)) ) : i in [2, 1,6]];
      [ 1, 2, 2 ]
      > T := RootDatum( "D4" : Twist:=<{{2}},6> );
      > T;
      T: Twisted adjoint root datum of dimension 4 of type 6D4,1
      > RelativeRootDatum(T);
      Adjoint root datum of type BC1
      > GammaOrbitsRepresentatives(T,1);
      [ 11, 5 ]
      > GammaOrbitsRepresentatives(T,2);
      [ 12 ]

.. magma:function:: CoxeterForm(R)
   :input_types: RootDtm
   :output_types: AlgMatElt
   :label: CoxeterForm_RootDtm

.. magma:function:: DualCoxeterForm(R)
   :input_types: RootDtm
   :output_types: AlgMatElt
   :label: DualCoxeterForm_RootDtm
   :parameters: Basis : MonStgElt : ``Standard"

   The matrix of an inner product on the (co)root space of the root datum :math:`R`
   which is invariant under the action of the (co)roots. The inner product is
   normalised so that the short roots in each irreducible component have length
   one.

.. _SubsectRDRootAction:

.. _rootrefl:

Reflections
-----------

The root :math:`\alpha` acts on the root space via the reflection
:math:`s_\alpha`; the coroot :math:`\alpha^\star` acts on the coroot space via
the coreflection :math:`s_\alpha^\star`.

.. magma:function:: SimpleReflectionMatrices(R)
   :input_types: RootDtm
   :output_types: []
   :label: SimpleReflectionMatrices_RootDtm

.. magma:function:: SimpleCoreflectionMatrices(R)
   :input_types: RootDtm
   :output_types: []
   :label: SimpleCoreflectionMatrices_RootDtm
   :parameters: Basis : MonStgElt : ``Standard"

   The sequence of matrices giving the action of the simple (co)roots of the root
   datum :math:`R` on the (co)root space, i.e. the matrices of
   :math:`s_{\alpha_1},\dots,s_{\alpha_n}` (respectively,
   :math:`s_{\alpha_1}^\star,\dots,s_{\alpha_n}^\star`).

.. magma:function:: ReflectionMatrices(R)
   :input_types: RootDtm
   :output_types: []
   :label: ReflectionMatrices_RootDtm

.. magma:function:: CoreflectionMatrices(R)
   :input_types: RootDtm
   :output_types: []
   :label: CoreflectionMatrices_RootDtm
   :parameters: Basis : MonStgElt : ``Standard"

   The sequence of matrices giving the action of the (co)roots of the root datum
   :math:`R` on the (co)root space, i.e. the matrices of
   :math:`s_{\alpha_1},\dots,s_{\alpha_{2N}}` (respectively,
   :math:`s_{\alpha_1}^\star,\dots,s_{\alpha_{2N}}^\star`).

.. magma:function:: ReflectionMatrix(R, r)
   :input_types: RootDtm, RngIntElt
   :output_types: []
   :label: ReflectionMatrix_RootDtm_RngIntElt

.. magma:function:: CoreflectionMatrix(R, r)
   :input_types: RootDtm, RngIntElt
   :output_types: []
   :label: CoreflectionMatrix_RootDtm_RngIntElt
   :parameters: Basis : MonStgElt : ``Standard"

   The matrix giving the action of the :math:`r`\ th (co)root of the root datum
   :math:`R` on the (co)root space, i.e. the matrix of :math:`s_{\alpha_r}`
   (respectively, :math:`s_{\alpha_r}^\star`).

.. magma:function:: SimpleReflectionPermutations(R)
   :input_types: RootDtm
   :output_types: []
   :label: SimpleReflectionPermutations_RootDtm

   The sequence of permutations giving the action of the simple (co)roots of the
   root datum :math:`R` on the (co)roots. This action is the same for roots and
   coroots.

.. magma:function:: ReflectionPermutations(R)
   :input_types: RootDtm
   :output_types: []
   :label: ReflectionPermutations_RootDtm

   The sequence of permutations giving the action of the (co)roots of the root
   datum :math:`R` on the (co)roots. This action is the same for roots and coroots.

.. magma:function:: ReflectionPermutation(R, r)
   :input_types: RootDtm, RngIntElt
   :output_types: []
   :label: ReflectionPermutation_RootDtm_RngIntElt

   The permutation giving the action of the :math:`r`\ th (co)root of the root
   datum :math:`R` on the (co)roots. This action is the same for roots and coroots.

.. magma:function:: ReflectionWords(R)
   :input_types: RootDtm
   :output_types: []
   :label: ReflectionWords_RootDtm

   The sequence of words in the simple reflections for all the reflections of the
   root datum :math:`R`. These words are given as sequences of integers. In other
   words, if :math:`a = [a_1,\dots,a_l] = \hbox{\tt ReflectionWords(R)[r]}`, then
   :math:`s_{\alpha_r} = s_{\alpha_{a_1}} \cdots s_{\alpha_{a_l}}`.

.. magma:function:: ReflectionWord(R, r)
   :input_types: RootDtm, RngIntElt
   :output_types: []
   :label: ReflectionWord_RootDtm_RngIntElt

   The word in the simple reflections for the :math:`r`\ th reflection of the root
   datum :math:`R`. The word is given as a sequence of integers. In other words, if
   :math:`a = [a_1,\dots,a_l] = \hbox{\tt ReflectionWord(R,r)}`, then
   :math:`s_{\alpha_r} = s_{\alpha_{a_1}} \cdots s_{\alpha_{a_l}}`.

.. magma:example:: Example: Action
   :label: Action

   .. code-block:: magma

      > R := RootDatum("A3" : Isogeny := 2);
      > mx := ReflectionMatrix(R, 4);
      > perm := ReflectionPermutation(R, 4);
      > wd := ReflectionWord(R, 4);
      > RootPosition(R, Root(R,2) * mx) eq 2^perm;
      true
      %%a> assert $1;
      > perm eq &*[ ReflectionPermutation(R, r) : r in wd ];
      true
      %%a> assert $1;
      > 
      > mx := CoreflectionMatrix(R, 4);
      > CorootPosition(R, Coroot(R,2) * mx) eq 2^perm;
      true
      %%a> assert $1;

.. _SubsectRDRootOp:

.. _ops-root-coroot:

Operations and Properties for Root and Coroot Indices
-----------------------------------------------------

.. magma:function:: Sum(R, r, s)
   :input_types: RootDtm, RngIntElt, RngIntElt
   :output_types: RngIntElt
   :label: Sum_RootDtm_RngIntElt_RngIntElt

   The index of the sum of the :math:`r`\ th and :math:`s`\ th roots in the root
   datum :math:`R`, or 0 if the sum is not a root. In other words, if
   :math:`t = \hbox{\tt Sum(R,$r$,$s$)} \ne 0` then
   :math:`\alpha_t=\alpha_r+\alpha_s`. The condition :math:`\alpha_r\ne\pm\alpha_s`
   must be satisfied.

.. magma:function:: IsPositive(R, r)
   :input_types: RootStr, RngIntElt
   :output_types: BoolElt
   :label: IsPositive_RootStr_RngIntElt

   Returns ``true`` if, and only if, the :math:`r`\ th (co)root of the root datum
   :math:`R` is a positive root.

.. magma:function:: IsNegative(R, r)
   :input_types: RootStr, RngIntElt
   :output_types: BoolElt
   :label: IsNegative_RootStr_RngIntElt

   Returns ``true`` if, and only if, the :math:`r`\ th (co)root of the root datum
   :math:`R` is a negative root.

.. magma:function:: Negative(R, r)
   :input_types: RootStr, RngIntElt
   :output_types: RngIntElt
   :label: Negative_RootStr_RngIntElt

   The index of the negative of the :math:`r`\ th (co)root of the root datum
   :math:`R`. In other words, if :math:`s = \hbox{\tt Negative(R,$r$)}` then
   :math:`\alpha_s=-\alpha_r`.

.. magma:function:: LeftString(R, r, s)
   :input_types: RootDtm, RngIntElt, RngIntElt
   :output_types: RngIntElt
   :label: LeftString_RootDtm_RngIntElt_RngIntElt

   Indices in the root datum :math:`R` of the left string through :math:`\alpha_s`
   in the direction of :math:`\alpha_r`, i.e. the indices of
   :math:`\alpha_s-\alpha_r,\alpha_s-2\alpha_r,\dots,\alpha_s-p\alpha_r`. In other
   words, this returns the sequence :math:`[r_1,\dots,r_p]` where
   :math:`\alpha_{r_i}=\alpha_s-i\alpha_r` and :math:`\alpha_s-(p+1)\alpha_r` is
   not a root. The condition :math:`\alpha_r\ne\pm\alpha_s` must be satisfied.

.. magma:function:: RightString(R, r, s)
   :input_types: RootDtm, RngIntElt, RngIntElt
   :output_types: RngIntElt
   :label: RightString_RootDtm_RngIntElt_RngIntElt

   Indices in the root datum :math:`R` of the left string through :math:`\alpha_s`
   in the direction of :math:`\alpha_r`, i.e. the indices of
   :math:`\alpha_s+\alpha_r,\alpha_s+2\alpha_r,\dots,\alpha_s+q\alpha_r`. In other
   words, this returns the sequence :math:`[r_1,\dots,r_q]` where
   :math:`\alpha_{r_i}=\alpha_s+i\alpha_r` and :math:`\alpha_s+(q+1)\alpha_r` is
   not a root. The condition :math:`\alpha_r\ne\pm\alpha_s` must be satisfied.

.. magma:function:: \name{IntrLeftStringLength}{LeftStringLength}(R, r, s)
   :input_types: RootDtm, RngIntElt, RngIntElt
   :output_types: RngIntElt

   The largest :math:`p` such that :math:`\alpha_s-p\alpha_r` is a root of the root
   datum :math:`R`. The condition :math:`\alpha_s\ne\pm\alpha_r` must be satisfied.

.. magma:function:: \name{IntrRightStringLength}{RightStringLength}(R, r, s)
   :input_types: RootDtm, RngIntElt, RngIntElt
   :output_types: RngIntElt

   The largest :math:`q` such that :math:`\alpha_s+q\alpha_r` is a root of the root
   datum :math:`R`. The condition :math:`\alpha_s\ne\pm\alpha_r` must be satisfied.

.. magma:example:: Example: Root Arithmetic
   :label: RootArithmetic

   .. code-block:: magma

      > R := RootDatum("G2");
      > Sum(R, 1, Negative(R,5));
      10
      %%a> assert $1 eq 10;
      > IsPositive(R, 10);
      false
      %%a> assert not $1;
      > Negative(R, 10);
      4
      %%a> assert $1 eq 4;
      > P := PositiveRoots(R);
      > P[1] - P[5] eq -P[4];
      true
      %%a> assert $1;

.. magma:function:: RootHeight(R, r)
   :input_types: RootStr, RngIntElt
   :output_types: RngIntElt
   :label: RootHeight_RootStr_RngIntElt

.. magma:function:: CorootHeight(R, r)
   :input_types: RootStr, RngIntElt
   :output_types: RngIntElt
   :label: CorootHeight_RootStr_RngIntElt

   The height of the :math:`r`\ th (co)root of the root datum :math:`R`, i.e. the
   sum of the coefficients of :math:`\alpha_r` (respectively,
   :math:`\alpha_r^\star`) with respect to the simple (co)roots.

.. magma:function:: RootNorms(R)
   :input_types: RootStr
   :output_types: [RngIntElt]
   :label: RootNorms_RootStr

.. magma:function:: CorootNorms(R)
   :input_types: RootStr
   :output_types: [RngIntElt]
   :label: CorootNorms_RootStr

   The sequence of squares of the lengths of the (co)roots of the root datum
   :math:`R`.

.. magma:function:: RootNorm(R, r)
   :input_types: RootStr, RngIntElt
   :output_types: RngIntElt
   :label: RootNorm_RootStr_RngIntElt

.. magma:function:: CorootNorm(R, r)
   :input_types: RootStr, RngIntElt
   :output_types: RngIntElt
   :label: CorootNorm_RootStr_RngIntElt

   The square of the length of the :math:`r`\ th (co)root of the root datum
   :math:`R`.

.. magma:function:: IsLongRoot(R, r)
   :input_types: RootStr, RngIntElt
   :output_types: BoolElt
   :label: IsLongRoot_RootStr_RngIntElt

   Returns ``true`` if, and only if, the :math:`r`\ th root of the root datum
   :math:`R` is long. This only makes sense for irreducible crystallographic root
   data. Note that for non-reduced root data, the roots which are not indivisible,
   are actually longer than the long ones.

.. magma:function:: IsShortRoot(R, r)
   :input_types: RootStr, RngIntElt
   :output_types: BoolElt
   :label: IsShortRoot_RootStr_RngIntElt

   Returns ``true`` if, and only if, the :math:`r`\ th root of the root datum
   :math:`R` is short. This only makes sense for irreducible crystallographic root
   data.

.. magma:function:: IsIndivisibleRoot(R, r)
   :input_types: RootStr, RngIntElt
   :output_types: BoolElt
   :label: IsIndivisibleRoot_RootStr_RngIntElt

   Returns ``true`` if, and only if, the :math:`r`\ th root of the root system
   :math:`R` is indivisible.

.. magma:example:: Example: Root Operations
   :label: RootOperations

   Note that the Coxeter form is defined over the rationals. Since it is not
   possible to multiply a lattice element by a rational matrix, (co)roots must be
   coerced into a rational vector space first.

   .. code-block:: magma

      > R := RootDatum("G2");
      > RootHeight(R, 5);
      4
      %%a> assert $1 eq 4;
      > F := CoxeterForm(R);
      > v := VectorSpace(Rationals(),2) ! Root(R, 5);
      > (v*F, v) eq RootNorm(R, 5);
      true
      %%a> assert $1;
      > IsLongRoot(R, 5);
      true
      %%a> assert $1;
      > LeftString(R, 1, 5);
      [ 4, 3, 2 ]
      > roots := Roots(R);
      > for i in [1..3] do
      >   RootPosition(R, roots[5]-i*roots[1]);
      > end for;
      4
      3
      2

.. magma:function:: RootClosure(R, S)
   :input_types: RootDtm, SetEnum[RngIntElt]
   :output_types: SetEnum[RngIntElt]
   :label: RootClosure_RootDtm_SetEnum_RngIntElt

   The closure in the root datum :math:`R` of the set :math:`S` of root indices.
   That is the indices of every root that can be written as a sum of roots with
   indices in :math:`S`.

.. magma:function:: AdditiveOrder(R)
   :input_types: RootStr
   :output_types: SeqEnum
   :label: AdditiveOrder_RootStr

   An additive order on the positive roots of the root datum :math:`R`, i.e. a
   sequence containing the numbers :math:`1,\dots,N` in some order such that
   :math:`\alpha_r+\alpha_s=\alpha_t` implies :math:`t` is between :math:`r` and
   :math:`s`. This is computed using the techniques of :cite:`Papi`

.. magma:function:: IsAdditiveOrder(R, Q)
   :input_types: RootStr, [RngIntElt]
   :output_types: BoolElt
   :label: IsAdditiveOrder_RootStr_RngIntElt

   Returns ``true`` if, and only if, :math:`Q` gives an additive order on a set of
   positive roots of :math:`R`. :math:`Q` must be a sequence of integers in the
   range :math:`[1..N]` with no gaps or repeats.

.. magma:example:: Example: Additive Order
   :label: AdditiveOrder

   .. code-block:: magma

      > R := RootDatum("A5");
      > a := AdditiveOrder(R);
      > Position(a, 2);
      6
      %%a> assert $1 eq 6;
      > Position(a, 3);
      10
      %%a> assert $1 eq 10;
      > Position(a, Sum(R, 2, 3));
      7
      %%a> assert $1 eq 7;

.. _SubsectRDRootWeight:

.. _weights:

Weights
-------

.. magma:function:: WeightLattice(R)
   :input_types: RootDtm
   :output_types: Lat
   :label: WeightLattice_RootDtm

   The weight lattice :math:`\Lambda` of the root datum :math:`R`. i.e. the
   :math:`\lambda` in :math:`{\mathbb{Q}}\Phi\le{\mathbb{Q}}\otimes X` such that
   :math:`\langle\lambda,\alpha^\star\rangle\in{\mathbb{Z}}` for every coroot
   :math:`\alpha^\star`.

.. magma:function:: CoweightLattice(R)
   :input_types: RootDtm
   :output_types: Lat
   :label: CoweightLattice_RootDtm

   The coweight lattice :math:`\Lambda^\star` of the root datum :math:`R`, i.e. the
   :math:`\lambda^\star` in :math:`{\mathbb{Q}}\Phi^\star\le{\mathbb{Q}}\otimes Y`
   such that :math:`\langle\alpha,\lambda^\star\rangle\in{\mathbb{Z}}` for every
   root :math:`\alpha`.

.. magma:function:: FundamentalWeights(R)
   :input_types: RootDtm
   :output_types: Mtrx
   :label: FundamentalWeights_RootDtm
   :parameters: Basis : MonStgElt : ``Standard"

   The fundamental weights :math:`\lambda_1,\dots,\lambda_n` of the root datum
   :math:`R` given as the rows of a matrix. This is the basis of the weight lattice
   :math:`\Lambda` dual to the simple coroots,
   i.e. :math:`\langle\lambda_i,\alpha_j^\star\rangle=\delta_{ij}`.

.. magma:function:: FundamentalCoweights(R)
   :input_types: RootDtm
   :output_types: Mtrx
   :label: FundamentalCoweights_RootDtm
   :parameters: Basis : MonStgElt : ``Standard"

   The fundamental coweights :math:`\lambda_1^\star,\dots,\lambda_n^\star` of the
   root datum :math:`R` given as the rows of a matrix. This is the basis of the
   coweight lattice :math:`\Lambda^\star` dual to the simple roots,
   i.e. :math:`\langle\alpha_i,\lambda_j^\star\rangle=\delta_{ij}`.

.. magma:example:: Example: Weights
   :label: Weights

   .. code-block:: magma

      > R := RootDatum("E6");
      > WeightLattice(R);
      Lattice of rank 6 and degree 6
      Basis:
      (4  3  5  6  4  2)
      (3  6  6  9  6  3)
      (5  6 10 12  8  4)
      (6  9 12 18 12  6)
      (4  6  8 12 10  5)
      (2  3  4  6  5  4)
      Basis Denominator: 3
      > FundamentalWeights(R);
      [ 4/3    1  5/3    2  4/3  2/3]
      [   1    2    2    3    2    1]
      [ 5/3    2 10/3    4  8/3  4/3]
      [   2    3    4    6    4    2]
      [ 4/3    2  8/3    4 10/3  5/3]
      [ 2/3    1  4/3    2  5/3  4/3]

.. magma:function:: IsDominant(R, v)
   :input_types: RootDtm, .
   :output_types: ModTupFldElt, GrpFPCoxElt
   :label: IsDominant_RootDtm
   :parameters: Basis : MonStgElt : ``Standard"

   Returns ``true`` if, and only if, :math:`v` is a dominant weight for the root
   datum :math:`R`, ie, a nonnegative integral linear combination of the
   fundamental weights.

.. magma:function:: DominantWeight(R, v)
   :input_types: RootDtm, .
   :output_types: ModTupFldElt, GrpFPCoxElt
   :label: DominantWeight_RootDtm
   :parameters: Basis : MonStgElt : ``Standard"

   The unique dominant weight in the same :math:`W`-orbit as the weight :math:`v`,
   where :math:`W` is the Weyl group of the root datum :math:`R`. The second value
   returned is a Weyl group element taking :math:`v` to the dominant weight. The
   weight :math:`v` can be given either as a vector or as a sequence representing
   the vector and is coerced into the weight lattice first.

.. magma:function:: WeightOrbit(R, v)
   :input_types: RootDtm, .
   :output_types: {@ ModTupFldElt @}, [GrpFPCoxElt]
   :label: WeightOrbit_RootDtm
   :parameters: Basis : MonStgElt : ``Standard"

   The :math:`W`-orbit of the weight :math:`v` as an indexed set, where :math:`W`
   is the Weyl group of the root datum :math:`R`. The first element in the orbit is
   always dominant. The second value returned is a sequence of Weyl group elements
   taking the weight to the corresponding element of the orbit. The weight
   :math:`v` can be given either as a vector or as a sequence representing the
   vector and is coerced into the weight lattice first.

.. magma:example:: Example: Dominant Weights
   :label: DominantWeights

   .. code-block:: magma

      > R := RootDatum("B3");
      > DominantWeight(R, [1,-1,0] : Basis:="Weight");  
      (1 0 0)
      [ 2, 3, 2, 1 ]
      > #WeightOrbit(R, [1,-1,0] : Basis:="Weight");   
      6
      %%a> assert $1 eq 6;
