atlas  0.6
tits.h
Go to the documentation of this file.
1 /*
2  This is tits.h
3 
4  Copyright (C) 2004,2005 Fokko du Cloux
5  Copyright (C) 2006-2016 Marc van Leeuwen
6  part of the Atlas of Lie Groups and Representations
7 
8  For license information see the LICENSE file
9 */
10 
11 /*
12  Class definitions and function declarations for the classes TitsGroup
13  and TitsElt.
14 */
15 
16 #ifndef TITS_H /* guard against multiple inclusions */
17 #define TITS_H
18 
19 
20 #include "tags.h"
21 #include "ratvec.h" // |RatWeight| contained in |TorusElement|
22 #include "arithmetic_fwd.h"
23 
24 #include "../Atlas.h"
25 
26 #include "bitvector.h" // contained in |TitsGroup|
27 #include "prerootdata.h" // contained in |GlobalTitsGroup|
28 #include "weyl.h" // contained in |TitsElt|
29 
30 #include "y_values.h"
31 
32 #include "cartanclass.h"
33 
34 namespace atlas {
35 
36 namespace tits {
37 
38 /******** function declarations *********************************************/
39 
40  // 2-subgroup by which each |TorusPart| at involution |inv| will be reduced
42 
43  // among imaginary generators in |imag| flag compact ones for |t|
45  (const RootDatum& rd, const TorusElement& t, RankFlags imag);
46 
47  // among imaginary generators in |imag| flag compact ones for |a|
49  (const TitsCoset& Tc, const TitsElt& a, RankFlags imag);
50 
51 /******** type definitions **************************************************/
52 
53 
54 /* Element of (Z/2Z)^rank, representing an element of H(2).
55 
56  The cocharacter lattice X_*(T) of T is always represented by Z^rank; the map
57  X_*(T)-> T given by lambda^vee \mapsto exp(pi i lambda^vee) has 2X_*(T) as
58  kernel, and induces a bijection of X_*(T)/2X_*(T) with the group H(2) of
59  elements of order 2; hence H(2) is represented by (Z/2Z)^rank
60 */
61  typedef SmallBitVector TorusPart;
62 
63 
64 
65 
67 {
68  friend class GlobalTitsGroup; // which does almost all of the work for us
69 
70  // element stored as $(t,w)$ is interpreted as $t * \sigma_w * \delta_1$
71  TorusElement t;
73 
74  public:
75 
76  // Construct the identity element in the group
77  explicit GlobalTitsElement(size_t rank) : t(rank),w() {}
78 
79  // The canonical representative $\sigma_w$ of |w| in |Tits|.
80  GlobalTitsElement(const WeylElt& we,size_t rank) : t(rank),w(we) {}
81 
82  explicit GlobalTitsElement(const TorusElement& te) : t(te),w() {}
83 
84  GlobalTitsElement(const TorusElement& te, const WeylElt& we)
85  : t(te),w(we) {}
86 
87  // we compute modulo $t.\sigma_w\delta\equiv\sigma_w\delta.t$
88  // therefore no constructor to form $\sigma_w\delta.t$ is needed
89 
90 // copy and assignment can be left to their defaults
91 
92 // accessors
93 
94 // both components are exposed as constant references:
95 
96  const TorusElement& torus_part() const { return t; }
97 // twisted involution whose fiber we are in
98  const TwistedInvolution& tw() const { return w; }
99 
100 // a method defined without help of |GlobalTitsGroup| (and which ignores |w|)
101 // requires simple-imaginary |alpha| that is integral on |t|; however unless
102 // all roots are integral on |t|, these conditions might be contradictory
104  (const RootDatum& dual_rd, // dual for pragmatic reasons
105  RootNbr alpha) const; // any simple-imaginary root
106 
107 
108 // manipulators
109  TorusElement& torus_part() { return t; } // one may modify just torus part
110 
111 
112 // STL obligatories
113  bool operator== (const GlobalTitsElement& a) const
114  { return w == a.w and t == a.t; }
115 
116  bool operator!= (const GlobalTitsElement& a) const
117  { return w != a.w or t != a.t; }
118 
119  bool operator< (const GlobalTitsElement& a) const // comparison, for STL use
120  { return w!=a.w ? w<a.w : t<a.t ; }
121 
122 }; // |class GlobalTitsElement|
123 
124 
125 
126 // |class GlobalTitsGroup|
127 
128 /*
129  |GlobalTitsGroup| is a support class for working with |GlobalTitsElement|
130  values. The main purpose is to allow defining cross actions and (inverse)
131  Cayley transforms of such elements, producing new ones. The modular
132  reduction of the |TorusElement| component that could be applied after
133  Cayley transforms (and should be for deciding equality) is not implemented
134  here, since it depends on the twisted involution in a way that is more
135  efficiently handled by tabulation than by on-the-fly computation.
136 
137  This class could be an alternative to the older |TitsGroup| and |TitsCoset|
138  support classes handling |x| values. It is then attached to a whole inner
139  class rather than to a specific real form or just a square class of them,
140  as |TitsCoset| is, whence the "Global". As a consequence it can generate
141  "all" valid elements for it (the command 'X'). For the latter purpose the
142  |square_class_gen| member and associated method are included, which permits
143  listing a set of initial elements from which others can be deduced.
144  */
145 class GlobalTitsGroup : public TwistedWeylGroup
146 {
147  const PreRootDatum prd; // from DUAL side, allows W action
148  WeightInvolution delta_tr; // transposed distinguished involution
149  std::vector<TorusPart> alpha_v; // |simple.roots()| reduced modulo 2
151 
152  // a list of gradings of the imaginary simple roots generating square classes
153  std::vector<Grading> square_class_gen;
154 
155 // forbid copy and assignment
157  GlobalTitsGroup& operator= (const GlobalTitsGroup&);
158 
159  public:
160  // for implementing 'X' for inner class (when latter is fully constructed)
161  GlobalTitsGroup(const InnerClass& G);
162 
163  // accessors
164  size_t semisimple_rank() const { return alpha_v.size(); }
165  size_t rank() const { return prd.rank(); }
166 
167  TorusElement torus_element_offset () const // implicit in each |TorusElement|
168  { return y_values::exp_2pi(half_rho_v); } // used only ub |block_io| for 'X'
169 
170  // Element m_\alpha of H(2) for simple coroot \#j.
171  TorusPart m_alpha(size_t j) const { return alpha_v[j]; }
172 
173  // Reflection of |TorusElement|s defined by a twisted involution.
174  // This matrix is negated-transposed w.r.t. |tw| (so |-delta_tr| if $tw=e$)
175  WeightInvolution involution_matrix(const WeylElt& tw) const;
176 
177  using TwistedWeylGroup::twisted; // overloaded in this class
178  using TwistedWeylGroup::dual_twisted; // overloaded in this class
179  using TwistedWeylGroup::twist; // idem
180 
181  TorusElement twisted(const TorusElement& x) const;
182  TorusElement dual_twisted(const TorusElement& x) const;
183 //void twist(TorusElement& x) const { x = twisted(x); }
184 
185 
186  const std::vector<Grading>& square_class_generators() const
187  { return square_class_gen; }
188 
189 
190 // methods that operate on an isolated |TorusElement|
191 
192  void complex_cross_act(weyl::Generator s,TorusElement& t) const
193  { t.simple_reflect(prd,s); } // OK since |prd| on dual side for |t|
194  void imaginary_cross_act(weyl::Generator s,TorusElement& t) const;
195 
196 // methods that only access some |GlobalTitsElement|
197 
198  // whether |a| is strong involution; if |not check_tw| assume |a.tw()| is OK
199  bool is_valid(const GlobalTitsElement& a,bool check_tw=false) const;
200  bool is_valid(const GlobalTitsElement& a, // weaker condition: square being
201  const SubSystem& sub) const; // central in subgroup
203  { return GlobalTitsElement(twisted(a.t),twisted(a.w)); }
205  { return GlobalTitsElement(dual_twisted(a.t),dual_twisted(a.w)); }
206 
207 
208  // determine status of simple root, if assumed imaginary
209  bool compact(weyl::Generator s, const TorusElement& t) const
210  { return t.negative_at(prd.simple_coroots()[s]); }
211  bool compact(weyl::Generator s, const GlobalTitsElement& a) const
212  { return compact(s,a.torus_part()); }
213 
214  // compute Cayley transform
216  { leftMult(a.w,s); return a; }
217  // flag length-decreasing complex cross actions and inverse Cayley transforms
218  RankFlags descents(const GlobalTitsElement& a) const;
219 
220  TorusElement theta_tr_times_torus(const GlobalTitsElement& a) const;
221 
222  // the square of a torus element, omitting (central) $\exp(2i\pi\check\rho)$
223  // this shift ensures that quasisplit strong involutions return the identity
224  TorusElement square_shifted(const GlobalTitsElement& a) const;
225 
226  GlobalTitsElement prod(const GlobalTitsElement& a,
227  const GlobalTitsElement& b) const;
228 
229  bool compact(const RootSystem& rs,
230  RootNbr alpha, // assumed imaginary
231  GlobalTitsElement a) const; // whether alpha compact
232 
233 // methods that manipulate a |GlobalTitsElement|
234 
235 /*
236  Twisted conjugates |a| by |sigma_alpha| where |alpha| is simple root \#s,
237  returns length change in $\{-1,0,+1\}$.
238 
239  This is implemented only modulo conjugation by torus elements, so there is
240  no effective difference with conjugation by the inverse of |sigma_alpha|
241 */
242  int cross_act(weyl::Generator s, GlobalTitsElement& a) const;
243  int cross_act(const WeylWord& w, GlobalTitsElement& a) const;
244  int cross_act(GlobalTitsElement& a,const WeylWord& w) const;
246  { cross_act(s,a); return a; }
247  GlobalTitsElement cross(const WeylWord& w, GlobalTitsElement a) const
248  { cross_act(w,a); return a; }
249  GlobalTitsElement cross(GlobalTitsElement a, const WeylWord& w) const
250  { cross_act(a,w); return a; }
251 
252  void add(TorusPart tp,GlobalTitsElement& a) const // |tp| by value: small
253  { a.t += tp; }
254 
255  // add |rw| to |t|
256  void add(const RatWeight& rw,TorusElement& t) const
257  { t += y_values::exp_2pi(rw); }
258 
259  void add(const RatWeight& rw,GlobalTitsElement& a) const
260  // the following would be necessary to get a true right-mulitplication
261  // involution_matrix(a.tw()).apply_to(rw.numerator()); // pull |rw| across
262  { add(rw,a.t); }
263 
264  // modify |t| or |a| to an inverse Cayley image by (real simple root) $s$
265  void do_inverse_Cayley(weyl::Generator s,TorusElement& t) const;
266  void do_inverse_Cayley(weyl::Generator s,GlobalTitsElement& a) const;
267 
268 }; // |class GlobalTitsGroup|
269 
270 
271 
272 
273 
274 // |class TitsElt|
275 
276 
277 /* We define two main classes, |TitsElt| and |TitsGroup|, as for Weyl groups.
278  A |TitsElt| value stores both a |WeylElt| value and a |TorusPart|,
279  which together specify the value. To compute with such elements however one
280  needs additional element-independent data stored in the associated
281  |TitsGroup| object, so many operations like multiplication are in fact
282  methods of the latter class. The Tits group contains a normal subgroup
283  isomorphic to $H(2)$ (the pure torus parts) for which the quotient is
284  canonically the Weyl group $W$. The group is not a semidirect product,
285  since $W$ does not lift to a subgroup, but each Weyl group element does
286  have a canonical lift (multiplication of such elements stays within the set
287  of canonical lifts if and only if the lengths add up). The values stored
288  represent an element in the quotient and an element in the coset of its
289  canonical lift. Computation is quite similar to what would be done for a
290  semidirect product, computing separately in the quotient and the coset, but
291  adjusting the computation in the coset in a way determined by the values in
292  the quotient.
293 
294  An important design decision that was made for |TitsElt| is that the class
295  should hide whether internally we represent a left or a right coset
296  (actually this decision was retrofitted onto an implementation that
297  initially did expose the choice it used, so that that the consequences of
298  this choice were hard to weed out). This means that we cannot expose any
299  form of reference to a "torus part", although we can export values computed
300  as left or right coset components. For the Weyl group part we can export a
301  constant reference, but not a variable one since changing it cannot leave
302  both left and right coset components unchanged. Also all computations with
303  |TitsElt| values need some access to the |TitsGroup| (most often by being
304  methods of that class), even though some would not need to use it depending
305  on the implementation. In order to make this possible, we are obliged to
306  declare the |TitsGroup| class a |friend| of |TitsElt|, but that's fine.
307 */
308 
309 /* We define |TitsElt| first, so |TitsGroup| inlines can call its methods; as
310  the opposite occurs also, we postpone those inlines of |titsElt|
311 */
312 
313 /* Represents an element of a Tits group.
314 
315  An element is always written $t.\sigma_w$, with $\sigma_w$ the canonical
316  lift to the Tits group of a Weyl group element $w$, and $t \in H(2)$.
317 */
318 class TitsElt
319 {
320 
321  friend class TitsGroup; // necessary, as |TitsGroup| manipulates |TitsElt|s
322 
323 
324  // Factor in H(2) of the Tits group element.
325  TorusPart d_t; // in fact thought of as to the left of |d_w|
326 
327 /* Canonical Weyl part of the Tits group element.
328 
329  If the Weyl group element $w$ has a reduced decomposition $s_1,...,s_r$,
330  then the canonical representative is the product of the corresponding Tits
331  group elements $\sigma_1,...,\sigma_r$. Because the $\sigma_i$ satisfy the
332  braid relations, this canonical representative is independent of the choice
333  of reduced decomposition.
334 */
335  weyl::TI_Entry d_w; // use |TI_Entry| rather than |WeylElt|, for |TE_Entry|
336 
337 
338  public:
339 
340 // constructors and destructors
341 
342 // All constructors take |TitsGroup| argument, though some do not need it
343 
344  // Construct the identity element in the group
345  explicit TitsElt(const TitsGroup& Tits);
346 
347  // The canonical representative $\sigma_w$ of |w| in |Tits|.
348  TitsElt(const TitsGroup& Tits,const WeylElt& w); // group defines rank
349 
350  TitsElt(const TitsGroup&, TorusPart t) // pure torus part
351  : d_t(t),d_w(WeylElt())
352  {}
353 
354  TitsElt(const TitsGroup&, const WeylElt& w, TorusPart t);
355 
356  TitsElt(const TitsGroup&, TorusPart t, const WeylElt& w)
357  : d_t(t),d_w(w)
358  {}
359 
360 // copy and assignment can be left to their defaults
361 
362 // accessors
363 
364 // only the Weyl group component is exposed as constant reference.
365 
366  // Canonical Weyl part of the Tits group element.
367  const WeylElt& w() const { return d_w; }
368 
369 /* the same componenent under another name (to make it smell sweeter); note
370  however that this returns a value, not a reference (to avoid making the
371  assumption here that |TwistedInvolution| is identical to |WeylElt|)
372  */
373  // twisted involution represented by canonical Weyl part
374  TwistedInvolution tw() const { return TwistedInvolution(d_w); }
375 
376 
377 // for the rest, only equality tests can bypass any use of the |TitsGroup|
378  bool operator== (const TitsElt& a) const
379  { return d_w == a.d_w and d_t == a.d_t; }
380 
381  bool operator!= (const TitsElt& a) const
382  { return d_w != a.d_w or d_t != a.d_t; }
383 
384  bool operator< (const TitsElt& a) const // comparison, for STL use
385  { // test torus part first, which is easier
386  return d_t != a.d_t ? d_t < a.d_t : d_w < a.d_w;
387  }
388 
389 // manipulators
390 
391  // in |reduce|, |V| should be modulo 2 reduction of image of $\theta-1$; as
392  // this is $\theta$-stable, reducing left or right torus part is the same
394  { d_t=V.mod_image(d_t); return *this; }
395 
396 /* exceptionally we expose the raw torus part to derived classes; this should
397  only be used for non-mathematical purposes like computing a hash code */
398  protected:
399  TorusPart t() const { return d_t; }
400 
401 // to use |hashCode| method, we also give access to |d_w| as a |TI_Entry|
402  const weyl::TI_Entry& ti() const { return d_w; }
403 
404 /* no public manipulators: any operation defined without using the Tits group
405  object would expose the implementation in an inacceptable way */
406 }; // |class TitsElt|
407 
408 
409 
410 
411 // |class TitsGroup|
412 
413 /*
414  Represents a finite subgroup of the normalizer in $G$ of the Cartan $H$.
415 
416  We use a slight variant of the Tits group (also called extended Weyl
417  group) as defined in J. Tits, J. of Algebra 4 (1966), pp. 96-116.
418 
419  The slight variant is that we include all elements of order two in the
420  torus, instead of just the subgroup generated by the $m_\alpha$ (denoted
421  $h_\alpha$ in Tits' paper.) Tits' original group may be defined by
422  generators $\sigma_\alpha$ for $\alpha$ simple, subject to the braid
423  relations and to $\sigma_\alpha^2= m_\alpha$; to get our group we just
424  add a basis of elements of $H(2)$ as additional generators, and express the
425  $m_\alpha$ in this basis. This makes for a simpler implementation, where
426  torus parts are just elements of the $\Z/2\Z$-vector space $H(2)$.
427 
428  We have not tried to be optimally efficient here, as it is not expected that
429  Tits computations will be significant computationally (dixit Fokko).
430 
431  Note on independence of choices: given a root $\alpha$ for $H$ in $G$,
432  the corresponding homomorphism $\phi_\alpha$ from $SL(2)$ to $G$ is
433  defined only up to conjugation by $H$. This means that the generator
434  $\sigma_\alpha$ of the Tits group appears to be defined only up to
435  multiplication by the image of the coroot $\alpha^\vee$. But we are
436  fixing a pinning, which means in particular that the maps $\phi_\alpha$
437  for $\alpha$ simple are canonically defined (by the requirement that the
438  standard pinning of $SL(2)$ be carried to the pinning for $G$). This means
439  that the generator $\sigma_\alpha$ (still for $\alpha$ simple) is
440  canonically defined.
441 */
442 class TitsGroup : public TwistedWeylGroup
443 {
444  // Dimension of the Cartan H. This is the size of torus parts of elements.
445  size_t d_rank;
446 
447 
448 /* List of the images in character lattice mod 2 of the simple roots.
449 
450  Regarded as elements of order two in the dual torus $T^\vee$, these are
451  the elements $m_\alpha^\vee$.
452 */
453  std::vector<TorusPart> d_simpleRoot;
454 
455  // List of the elements $m_\alpha$ (for $\alpha$ simple) in $H(2)$.
456  std::vector<TorusPart> d_simpleCoroot;
457 
458 /*
459  Transpose of the reduction mod 2 of the matrix of the defining
460  involution of the inner class.
461 
462  Gives the action of the (transposed fundamental) involution $\delta$ on
463  $H(2)$, for twisting TorusPart values when commuting with $\delta$.
464 */
466 
467  // action of $-w_0$ after applying |d_involution|
469 
470 // copy and assignment
471 // reserve and implement when necessary
472  TitsGroup(const TitsGroup&);
473  TitsGroup& operator= (const TitsGroup&);
474 
475  public:
476 
477 // constructors and destructors
478 
479  // Ordinary constructor for inner class
480  TitsGroup(const RootDatum&,
481  const WeylGroup& W,
482  const WeightInvolution& d);
483 
484  // Constructor for semisimple adjoint group
485  TitsGroup(const int_Matrix& Cartan_matrix,
486  const WeylGroup& W,
487  const weyl::Twist& twist);
488 
489  // Like a copy constructor, but reference |W| rather than share or copy
490  TitsGroup(const TitsGroup& Tg, const WeylGroup& W)
491  : TwistedWeylGroup(W,Tg.twist())
492  , d_rank(Tg.d_rank)
493  , d_simpleRoot(Tg.d_simpleRoot)
494  , d_simpleCoroot(Tg.d_simpleCoroot)
495  , d_involution(Tg.d_involution)
496  , dual_involution(Tg.dual_involution)
497  {}
498 
499 // All methods being accessors, we classify by behaviour w.r.t. TitsElt objects
500 
501 // methods not involving |TitsElt|
502 
503  // Rank of the torus.
504  const size_t rank() const { return d_rank; }
505  const size_t semisimple_rank() const
506  { return TwistedWeylGroup::rank(); }
507 
508  // Element m_\alpha of H(2) for simple coroot \#j.
509  TorusPart m_alpha(size_t j) const { return d_simpleCoroot[j]; }
510 
511  // Image in the character lattice mod 2 of simple root \#j.
512  TorusPart dual_m_alpha(size_t j) const { return d_simpleRoot[j]; }
513 
514 // methods only involving a |TorusPart|
515 
516  /* Apply to the element x of H(2) simple reflection s.
517 
518  This is the same thing as conjugating |x|, viewed as embedded in the Tits
519  group, by $\sigma_s$, or equivalently by its inverse (as
520  $\sigma_s^2$ commutes with $x$). This is used internally to compute
521  the proper commutation relations between Weyl group and torus parts of a
522  Tits element.
523  */
524  void reflect(TorusPart& x, weyl::Generator s) const
525  { if (d_simpleRoot[s].dot(x))
526  x += d_simpleCoroot[s];
527  }
528 
529 // convert between torus parts $x$ and $y$ for which $x.w=w.y$ in Tits group
530  TorusPart push_across(TorusPart x, const WeylElt& w) const;
531  TorusPart pull_across(const WeylElt& w, TorusPart y) const;
532 
533  using TwistedWeylGroup::twisted; // overloaded in this class
534  using TwistedWeylGroup::twist; // idem
535 
536  // Binary matrix*vector product to compute twist on torus part
537  TorusPart twisted(const TorusPart x) const { return d_involution*x; }
538  TorusPart dual_twisted(const TorusPart x) const { return dual_involution*x; }
539  TitsElt twisted(const TitsElt& te) const;
540  // dual twist adds in a shift (computed by |TitsCoset::is_dual_twist_stable|)
541  TitsElt dual_twisted(const TitsElt& te, const TorusPart shift) const;
542 
543  // In-place imperative version of |twisted(TorusPart x)|
544  void twist(TorusPart x) const { x=twisted(x); }
545 
546  // Reflection of |TorusPart|s defined by a twisted involution
547  BinaryMap involutionMatrix(const WeylWord& tw) const;
548 
549 
550 // methods that only access some |TitsElt|
551 
552  // Length of the underlying Weyl group element.
553  unsigned long length(const TitsElt& a) const
554  { return weylGroup().length(a.w()); }
555 
556  TorusPart left_torus_part(const TitsElt& a) const { return a.d_t; }
557 
558  TorusPart right_torus_part(const TitsElt& a) const
559  { return push_across(a.d_t,a.d_w); }
560 
561 
562 // methods that manipulate a |TitsElt|
563 
564 // left and right multiplication by $\sigma_s$ and by its inverse
565  void sigma_mult(weyl::Generator s,TitsElt& a) const;
566  void sigma_inv_mult(weyl::Generator s,TitsElt& a) const;
567  void mult_sigma(TitsElt&, weyl::Generator) const;
568  void mult_sigma_inv(TitsElt&, weyl::Generator) const;
569 
570  TitsElt prod(const TitsElt& a, TitsElt b) const; // "a * b"
571  void mult(TitsElt& a, const TitsElt& b) const { a=prod(a,b); } // "a *= b"
572 
573  void right_add(TitsElt& a,TorusPart t) const
574  { a.d_t += pull_across(a.d_w,t); }
575  void left_add (TorusPart t,TitsElt& a) const
576  { a.d_t += t; }
577 
578  // Conjugate |a| by $\sigma_\alpha$, where $\alpha=\alpha_s$.
580  {
581  sigma_mult(s,a); mult_sigma_inv(a,s);
582  }
583  // the inverse operation of |sigma_conjugate(a,s)|
585  {
586  sigma_inv_mult(s,a); mult_sigma(a,s);
587  }
588 
589 
590 /* Twisted conjugates the TitsElt |a| by |sigma_alpha| where |alpha| is
591  simple root \#s.
592 
593  This corresponds to conjugation of the coset a.delta, with delta the
594  defining involution of the inner class. Note that the inverse of the
595  generator \sigma_\alpha is \sigma_\alpha.m_\alpha. Therefore this operation
596  is \emph{not} in general an involution with respect to |a| for fixed |s|.
597  However, if for elements whose Weyl group part is a twisted involution the
598  torus parts are projected to the fiber group over that twisted involution,
599  as is done in the KGB construction, it induces an involution on the quotient
600  set.
601 */
603  { sigma_mult(s,a); mult_sigma_inv(a,twisted(s)); }
604 
605  // the inverse operation: twisted conjugation by $\sigma_s^{-1}$
607  { sigma_inv_mult(s,a); mult_sigma(a,twisted(s)); }
608 
609 // manipulators (none)
610 
611 
612 }; // |class TitsGroup|
613 
614 // postponed inlines of |TitsElt|
615 inline TitsElt::TitsElt(const TitsGroup& Tits)
616 : d_t(Tits.rank()), d_w(WeylElt())
617 {}
618 
619 inline TitsElt::TitsElt(const TitsGroup& Tits,const WeylElt& w)
620 : d_t(Tits.rank()), d_w(w)
621 {}
622 
623 inline TitsElt::TitsElt
624  (const TitsGroup& Tits, const WeylElt& w, TorusPart t)
625 : d_t(Tits.pull_across(w,t)), d_w(w)
626 {}
627 
628 struct TE_Entry // To allow hash tables of TitsElt values
629  : public TitsElt
630 {
631  TE_Entry(const TitsElt& t) : TitsElt(t) {}
632 
633  // members required for an Entry parameter to the HashTable template
634  typedef std::vector<TE_Entry> Pooltype; // associated storage type
635  size_t hashCode(size_t modulus) const // hash function
636  {
637  return (ti().hashCode(modulus)+t().data().to_ulong()) & (modulus-1);
638  }
639 }; // |class TE_Entry|
640 
641 
660 {
661  TitsGroup* my_Tits_group; // pointer indicating ownership
662  const TitsGroup& Tg;
663 
664  /*
665  Offset used to define conjugation action of $\delta$ on root vectors
666  $X_\alpha$ which must be an element of the root space for
667  $\beta=twist(\alpha)$. In fact we insist that $X_\alpha$ is set to plus or
668  minus $X_\beta$, the sign being given by |grading_offset[s]| where
669  $\alpha=\alpha_s$. The fact that $\delta$ is a strong involution implies
670  that the grading offset must always the same for $\alpha$ as for
671  $twist(\alpha)$.
672 
673  In term of |TitsElement|s, this relation implies the "commutation relation"
674  $\sigma_\alpha.\delta=m_\alpha^grading_offset[s].\delta.\sigma_\beta$
675  */
677 
678  const RootSystem& rs; // needed (only) for the |grading| method
679 
680  public:
681  TitsCoset(const InnerClass& G, Grading base_grading);
682 
683  TitsCoset(const InnerClass& G);// adjoint case
684 
685  TitsCoset(const InnerClass& G,
686  tags::DualTag);// dual adjoint case
687 
688  ~TitsCoset() { delete(my_Tits_group); }
689 
690  /* accessors */
691 
692  const TitsGroup& titsGroup() const { return Tg; }
693  const WeylGroup& weylGroup() const { return Tg.weylGroup(); }
694 
695  bool hasTwistedCommutation
697  { return Tg.hasTwistedCommutation(s,tw); }
698 
699  Grading base_grading() const { return grading_offset; }
700 
701  bool is_valid(TitsElt a) const; // whether |a| may occur at all; by-value
702 
703  // whether simple root |s| noncompact at KGB element represented by |a|
704  inline bool simple_grading(const TitsElt& a, size_t s) const;
705 
706  // grading of a KGB element at a simple-imaginary root: whether noncompact
707  bool simple_imaginary_grading(TorusPart x, RootNbr alpha) const;
708  // general grading of a KGB element at an imaginary root: whether noncompact
709  bool grading(TitsElt a, RootNbr alpha) const; // |a| by-value
710 
711 
712  // operation defining cross action of simple roots
713  inline void basedTwistedConjugate(TitsElt& a, size_t s) const;
714 
715  // when no equivalence of |TitsElt| values is to be allowed (extended blocks)
716  // a more strict implementation of twisted conjugations is called for
717  void strict_based_twisted_conjugate(TitsElt& a, size_t s) const;
718 
719  void basedTwistedConjugate(TitsElt& a, const WeylWord& w) const;
720  void basedTwistedConjugate(const WeylWord& w, TitsElt& a) const;
721 
722  // operation defining Cayley transform in non-compact imaginary simple roots
723  void Cayley_transform(TitsElt& a, size_t s) const
724  { Tg.sigma_mult(s,a); } // set |a| to $\sigma_s.a$
725 
726  // inverse Cayley transform for real simple roots
727  // this requires knowing the subspace by which torus part has been reduced
728  void inverse_Cayley_transform(TitsElt& a, size_t s,
729  const SmallSubspace& mod_space) const;
730 
731  // conjugate Tits group element by $\delta_1$
732  TitsElt twisted(const TitsElt& a) const;
733  // also keep a version for torus part only
734  TorusPart twisted(const TorusPart& t) const { return Tg.twisted(t);}
735 
736 }; // |class TitsCoset|
737 
738 // A richer version of |TitsCoset|, with more methods
740 {
741  // strong real form representative
743 
744  public:
745  EnrichedTitsGroup(const RealReductiveGroup&);
746 
747  cartanclass::fiber_orbit f_orbit() const { return srf.first; }
748  cartanclass::square_class square() const { return srf.second; }
749 
750  // whether arbitrary root |n| is compact for |x| in fundamental fiber
751  bool is_compact(const TorusPart& x, RootNbr n) const
752  { return not grading(TitsElt(titsGroup(),x),n); }
753 
754  TitsElt backtrack_seed (const InnerClass& G,
755  RealFormNbr rf, size_t cn) const;
756 
757 }; // |class EnrichedTitsGroup|
758 
759 // inline definitions (inlined here because of the long comments)
760 
761 /* The amazingly simple way to compute the grading at simple roots, for any
762  twisted involution for which they are imaginary. In short, the grading of
763  an element $\sigma_w.\delta$ with trivial torus part at any imaginary
764  simple root $\alpha=alpha_s$ is given by $grading_offset[s]$, regardless of
765  $w$ (provided it makes $\alpha$ imaginary); the case of a nontrivial torus
766  part follows easily from this basic case. Result |true| means noncompact.
767 
768  Let $w$ be the twisted involution associated to the Tits element |a| (i.e.,
769  its Weyl group part) and let $\alpha=\alpha_s$ be a simple root, with image
770  $\beta=\alpha_t$ under the twist associated to $\delta$ (so $t=twisted(s)$,
771  and $s=t$ if $\alpha$ is imaginary for $\delta$). The precondition is that
772  $s$ is imaginary for $\sigma_w.\delta$ which means that $s.w.t=w$ in $W$
773  and $l(s.w)>l(w)$, so that both members of $s.w=w.t$ are reduced. Therefore
774  $\sigma_s\sigma_w=\sigma_w\sigma_t$ in the Tits group, and
775  $\sigma_s\sigma_w\delta=m_s^{grading_offset[s]}.\sigma_w\delta.\sigma_s$.
776  Then $X_\alpha$ has eigenvalue $(-1)^grading_offset[s]$ for conjugation by
777  $\sigma_w.\delta$, in other words $grading_offset[s]$ is also the grading
778  of $\sigma_w.\delta$ at $\alpha$.
779 
780  Left multiplication of $\sigma_w.\delta$ by a torus element $x$ will modify
781  this grading to the opposite parity if and only if $\alpha(x)=-1$; since
782  this torus part $x$ is represented as a bitvector, we can take the scalar
783  product of the reduction mod 2 of $\alpha$ with $x$ to compute this
784  correction. The |!=|-operation, which on |bool| values means exclusive or,
785  combines the values.
786 
787  Note that by using the a left torus factor |x| rather than a right factor,
788  we need not refer to $\beta$, i.e., |(twisted(s))|, in the dot product.
789 */
790 inline
791 bool TitsCoset::simple_grading(const TitsElt& a, size_t s) const
792 {
793  return grading_offset[s] != Tg.dual_m_alpha(s).dot(Tg.left_torus_part(a));
794 }
795 
796 /* Apart from the grading methods, this is another place where we use
797  |grading_offset|. The task is to compute the conjugate of the strong
798  involution $a.x_0.\delta$ by $\sigma_s$ or by $\sigma_s^{-1}=\sigma_s^3$.
799  These differ by conjugation by the torus element $\sigma_s^2=m_s$, which is
800  not a trivial operation at the Tits group level, but as mentioned stays
801  within the equivalence relation of our interpretation of Tits elements.
802  Therefore only one operation is implemented, and it defines an involution
803  at the level of the KGB structure, generating for varying $s$ a $W$ action.
804 
805  For the twisted involution $w$ this operation is just twisted conjugation,
806  giving $w'=s.w.t$ where $t=twisted(s)$. For the entire Tits group part
807  $a=x.\sigma_w$, twisted conjugation by $\sigma_s$ in the Tits group |Tg|
808  gives an element $a'=x'.\sigma_{w'}$ such that $\sigma_s.a=a'.\sigma_t$.
809  Finally $\sigma_s.a.\delta=a'.\sigma_t.\delta=a'.\delta.\sigma_s.
810  m_s^{grading_offset[s]}$. Because of the equivalence in interpreting
811  |TitsElement| values, we may replace multiplication on the right by the
812  torus element $m_t^{grading_offset[s]}$ by multiplication on the left
813  leading to the formula implemented below.
814 */
815 inline
817 {
818  Tg.twistedConjugate(a,s);
819  if (grading_offset[s])
820  Tg.left_add(Tg.m_alpha(s),a);
821 }
822 
823 
824 } // |namespace tits|
825 
826 } // |namespace atlas|
827 
828 #endif
TitsElt & reduce(const SmallSubspace &V)
Definition: tits.h:393
const TwistedInvolution & tw() const
Definition: tits.h:98
WeylElt TwistedInvolution
Definition: Atlas.h:231
const WeylGroup & weylGroup() const
Definition: tits.h:693
unsigned short square_class
Definition: Atlas.h:312
TorusPart twisted(const TorusPart &t) const
Definition: tits.h:734
Grading base_grading() const
Definition: tits.h:699
bool compact(weyl::Generator s, const TorusElement &t) const
Definition: tits.h:209
GlobalTitsElement twisted(const GlobalTitsElement &a) const
Definition: tits.h:202
BitVector< constants::RANK_MAX > SmallBitVector
Definition: Atlas.h:181
TorusPart t() const
Definition: tits.h:399
TitsGroup(const TitsGroup &Tg, const WeylGroup &W)
Definition: tits.h:490
void add(TorusPart tp, GlobalTitsElement &a) const
Definition: tits.h:252
size_t rank() const
Definition: tits.h:165
TorusElement t
Definition: tits.h:71
Definition: tits.h:145
subquotient::Subspace< constants::RANK_MAX > SmallSubspace
Definition: Atlas.h:191
GlobalTitsElement simple_imaginary_cross(const RootDatum &dual_rd, RootNbr alpha) const
Definition: tits.cpp:73
void add(const RatWeight &rw, GlobalTitsElement &a) const
Definition: tits.h:259
bool operator!=(const GlobalTitsElement &a) const
Definition: tits.h:116
void inverseTwistedConjugate(TitsElt &a, weyl::Generator s) const
Definition: tits.h:606
BitSet< constants::RANK_MAX > RankFlags
Definition: Atlas.h:60
TE_Entry(const TitsElt &t)
Definition: tits.h:631
#define shift()
Definition: cweave.c:116
Definition: tits.h:66
const TitsGroup & Tg
Definition: tits.h:662
Definition: tits.h:628
TorusPart right_torus_part(const TitsElt &a) const
Definition: tits.h:558
const size_t rank() const
Definition: tits.h:504
void twist(TorusPart x) const
Definition: tits.h:544
const TitsGroup & titsGroup() const
Definition: tits.h:692
size_t d_rank
Definition: tits.h:445
WeightInvolution delta_tr
Definition: tits.h:148
unsigned long length(const TitsElt &a) const
Definition: tits.h:553
const WeylElt & w() const
Definition: tits.h:367
const size_t semisimple_rank() const
Definition: tits.h:505
size_t hashCode(size_t modulus) const
Definition: tits.h:635
bool is_compact(const TorusPart &x, RootNbr n) const
Definition: tits.h:751
void Cayley_transform(TitsElt &a, size_t s) const
Definition: tits.h:723
size_t semisimple_rank() const
Definition: tits.h:164
GlobalTitsElement(const TorusElement &te)
Definition: tits.h:82
void reflect(TorusPart &x, weyl::Generator s) const
Definition: tits.h:524
const PreRootDatum prd
Definition: tits.h:147
TorusElement torus_element_offset() const
Definition: tits.h:167
std::vector< TorusPart > d_simpleCoroot
Definition: tits.h:456
bool simple_grading(const TitsElt &a, size_t s) const
Definition: tits.h:791
GlobalTitsElement dual_twisted(const GlobalTitsElement &a) const
Definition: tits.h:204
TitsElt(const TitsGroup &, TorusPart t, const WeylElt &w)
Definition: tits.h:356
void sigma_mult(weyl::Generator s, TitsElt &a) const
Left multiplication of |a| by the canonical generator $$.
Definition: tits.cpp:489
TitsElt(const TitsGroup &Tits)
Definition: tits.h:615
const TorusElement & torus_part() const
Definition: tits.h:96
bool operator==(const GlobalTitsElement &a) const
Definition: tits.h:113
const std::vector< Grading > & square_class_generators() const
Definition: tits.h:186
friend class GlobalTitsGroup
Definition: tits.h:68
Definition: cweave.c:245
weyl::TI_Entry d_w
Definition: tits.h:335
void left_add(TorusPart t, TitsElt &a) const
Definition: tits.h:575
cartanclass::fiber_orbit f_orbit() const
Definition: tits.h:747
void twistedConjugate(TitsElt &a, weyl::Generator s) const
Definition: tits.h:602
const RatWeight half_rho_v
Definition: tits.h:150
TorusPart left_torus_part(const TitsElt &a) const
Definition: tits.h:556
~TitsCoset()
Definition: tits.h:688
BitVector< dim > mod_image(const BitVector< dim > &w) const
Definition: subquotient.h:117
GlobalTitsElement cross(GlobalTitsElement a, const WeylWord &w) const
Definition: tits.h:249
void sigma_inv_conjugate(TitsElt &a, weyl::Generator s) const
Definition: tits.h:584
Class definitions and function declarations for WeylGroup.
GlobalTitsElement Cayley(weyl::Generator s, GlobalTitsElement a) const
Definition: tits.h:215
bool compact(weyl::Generator s, const GlobalTitsElement &a) const
Definition: tits.h:211
GlobalTitsElement(size_t rank)
Definition: tits.h:77
std::vector< Grading > square_class_gen
Definition: tits.h:153
GlobalTitsElement(const WeylElt &we, size_t rank)
Definition: tits.h:80
TitsGroup * my_Tits_group
Definition: tits.h:661
void sigma_conjugate(TitsElt &a, weyl::Generator s) const
Definition: tits.h:579
void mult(TitsElt &a, const TitsElt &b) const
Definition: tits.h:571
TwistedInvolution tw() const
Definition: tits.h:374
SmallSubspace fiber_denom(const WeightInvolution &theta)
Definition: tits.cpp:854
TwistedInvolution w
Definition: tits.h:72
const cartanclass::StrongRealFormRep srf
Definition: tits.h:742
Definition: tits.h:318
TorusPart twisted(const TorusPart x) const
Definition: tits.h:537
cartanclass::square_class square() const
Definition: tits.h:748
Definition: weyl.h:780
struct subscription_node * sub
Definition: parse_types.h:102
std::vector< TorusPart > alpha_v
Definition: tits.h:149
A mapping between one interpretation of Generators and another.
Definition: weyl.h:53
Definition: tits.h:739
std::vector< TE_Entry > Pooltype
Definition: tits.h:634
unsigned short RealFormNbr
Definition: Atlas.h:302
void basedTwistedConjugate(TitsElt &a, size_t s) const
Definition: tits.h:816
TorusElement & torus_part()
Definition: tits.h:109
TorusPart m_alpha(size_t j) const
Definition: tits.h:171
int_Matrix WeightInvolution
Definition: Atlas.h:159
bool operator<(const GlobalTitsElement &a) const
Definition: tits.h:119
GlobalTitsElement(const TorusElement &te, const WeylElt &we)
Definition: tits.h:84
TorusPart dual_m_alpha(size_t j) const
Definition: tits.h:512
Definition: tits.h:442
Grading grading_offset
Definition: tits.h:676
unsigned long n
Definition: axis.cpp:77
TorusPart dual_twisted(const TorusPart x) const
Definition: tits.h:538
Definition: Atlas.h:38
Definition of dummy argument tags used for constructor overloading.
Definition: tags.h:51
std::vector< TorusPart > d_simpleRoot
Definition: tits.h:453
TorusPart m_alpha(size_t j) const
Definition: tits.h:509
TorusPart d_t
Definition: tits.h:325
TitsElt(const TitsGroup &, TorusPart t)
Definition: tits.h:350
GlobalTitsElement cross(const WeylWord &w, GlobalTitsElement a) const
Definition: tits.h:247
void complex_cross_act(weyl::Generator s, TorusElement &t) const
Definition: tits.h:192
BitMatrix< constants::RANK_MAX > BinaryMap
Definition: Atlas.h:185
unsigned short RootNbr
Definition: Atlas.h:216
TorusPart pull_across(const WeylElt &w, TorusPart y) const
Definition: tits.cpp:451
BinaryMap dual_involution
Definition: tits.h:468
SmallBitVector TorusPart
Definition: Atlas.h:256
unsigned short fiber_orbit
Definition: Atlas.h:310
const weyl::TI_Entry & ti() const
Definition: tits.h:402
unsigned char Generator
Definition: Atlas.h:226
GlobalTitsElement cross(weyl::Generator s, GlobalTitsElement a) const
Definition: tits.h:245
std::bitset< 32 > RankFlags
Definition: KLread.cpp:39
void add(const RatWeight &rw, TorusElement &t) const
Definition: tits.h:256
BinaryMap d_involution
Definition: tits.h:465
RankFlags Grading
Definition: Atlas.h:289
const RootSystem & rs
Definition: tits.h:678
TorusElement exp_2pi(const RatWeight &r)
Definition: y_values.h:108
Definition: tits.h:659
std::pair< fiber_orbit, square_class > StrongRealFormRep
Definition: Atlas.h:313
void right_add(TitsElt &a, TorusPart t) const
Definition: tits.h:573
Grading grading
Definition: output.cpp:73
Grading compact_simples(const RootDatum &rd, const TorusElement &t, RankFlags imag)
Definition: tits.cpp:861