Documentation contents

atlas Library · Script File

Vogan-dual.at

A first main objective of this script is to define a function |dual_KGB| that
associates to a |Param| value a KGB element for a computed dual real form.
Even just determining the proper dual real form is a surprisingly delicate
problem, especially for parameters with non integral infinitesimal character.
Source
atlas-scripts/Vogan-dual.at (256 lines)
Definitions
24
Loads
Loaded by
L_packet.at weak_packets.at dual.at

Definitions in source order

Commented-out code, lines 10–49 (38 lines)
  We start with with some technical functions that are no longer used, so they
  are commented out. The code are still useful as a construction of an element
  proving why the function |fixed_lift| below is guaranteed to succeed.

  It will be important to apply a shift to dual torus_factor values that are
  also stable under the dual involution. The function |rho_diff_integral| would
  compute the shift, and |theta_stable_diff| would call it at the bottom of a
  recurrence, at a KGB element |x0| without complex descents where the result is
  automatically $\theta$-stable, and move it stably back to the original |x|.

{ half sum of poscoroots for roots not integral on (torus element of) |z| }
set rho_diff_integral (RootDatum rd, ratvec z) = ratvec:
  rho_check(rd)-rho(integrality_datum(dual(rd),z))

{ |rho_diff_integral(z)|, but made $\theta$-stable by a sum-of-coroots shift.
  Here |x| just serves to record |theta=involution(x)|: such |x| is easy to
  build from |theta|, and |cross| is more efficient than matrix conjugation.

  Moving to different elements |x| is done by the cross action and reflections
  (applied at the right multiplied to rational coweights) before and after the
  recursion. With respect to a hypothetical direct call of |rho_diff_integral|,
  this introduces a shift by the complex coroot occurring in the move (due to
  the term |rho_check| above, which the reflection applied afterwards shifts).
}
set theta_stable_diff ((KGBElt, ratvec)(x,z):xz) = ratvec:
( assert(@:denom(z*real_posroots(x))=1,"Coroot not integral on real roots")
; let rd = RootDatum: real_form(x) then ssr = semisimple_rank(rd) in
  xz. { apply to original argument pair the following recursive function: }
  (rec_fun tsd (KGBElt x,ratvec z) ratvec:
     let s = first(ssr,(int i):status(i,x).=) { search complex descent }
     in if s<0 { no complex descents }
        then let res=rho_diff_integral(rd,z) in { found x0, get diff }
           assert (res*involution(x)=res,"unstable"); res
        else let rs=reflection(rd,s) in tsd(cross(s,x),z*rs)*rs
     fi
   )
)
  end of commented-out section

fixed_lift

L59fixed_lift (mat theta_1,ratvec z) = (ratvec,(vec,mat,mat))
Instead, we now exploit the fact that z is $\theta$-stable modulo 1
initially, and then find a $\theta$-stable lift here, given that it exists,
essentially by applying a section of theta-1 to the vector z*(theta-1)%1

Since the decomposition (d,L,R) of |theta-1| will also serve for the function
|integral_shift| defined below, we export that triple in the result
given a $\theta$-fixed torus element, find a $\theta$-fixed logarithm

integral_shift

L87integral_shift (ratvec v, mat simples,(vec d,mat L,mat R)) = vec
When restricting to a centraliser subgroup, we shall need to correct a
potential torus factor |tf| with respect to the changed system of imaginary
roots. The final correction is computed by |integral_shift| as an integer
vector, which moreover should be $\theta$-stable, so that whatever
correction is made will not change the square class that has been fixed
beforehand; the condition for which the correction is computed is to get the
proper grading on the simple-imaginary roots of the subsystem, which are
passed as |simples| argument. That grading undergoes two changes. Even if
|tf| remains valid, it grades imaginary roots indirectly through an offset
$\rho_im$; this means we must compensate for the grading change implied for
the difference of the offset between full system and subsystem. Apart from
that, we may have (had) to shift |tf| in order to get into the proper
(square class for the subsystem) coset. In order to compute the correction
we pass as |v| (not |tf| but) that shift made, minus to old $\rho_im$; the
new $\rho_im$ value is implicit in |simples| and is not included in the
passed value of |v|. So we must find an (integral) vector |w| such that for
all roots alpha in |simples|: < w , alpha > = < v , alpha > + 1 (mod 2).

We search |w| among the linear combinations of the rows of |L1| which span
the space of coweight fixed by theta, so that |w*theta=w| is assured.
Find for |p| the KGB element (|y|) in an appropriate dual real form.
The |dual_int_ic| argument should be |dual_integral(p.inner_class,gamma)| for
|gamma=p.infinitesimal_character|; the reason it is not computed here is that
historically doing so would not identify it with the an inner class computed
elsewhere identically (for instance for another parameter in the same block).
The atlas program currently would make such an identification; however
precomputing and passing it around is still more efficient, so we leave this.
L95
NOTE: the comment about |dual_int_ic| is wrong, it should be
dual_inner_class(p), which is (defined in parameters.at):
 dual(inner_class(integrality_datum(p.root_datum,p.infinitesimal_character),x.involution)
Rather than
 dual_integral(p.inner_class,p.infinitesimal_character), which is (defined in basic.at):
 inner_class(dual(integrality_datum(ic,p.infinitesimal_character)),-^distinguished_involution(ic))
  where ic=p.inner_class
L103

dual_KGB

L112dual_KGB (Param p, InnerClass dual_int_ic) = KGBElt

central_cocharacter

L147central_cocharacter (RealForm G) = ratvec
set dual_KGB (Param p, InnerClass dual_int_ic) = KGBElt:
  let x=x(p), dual_tf=infinitesimal_character(p) - lambda(p)
  then dual_theta = -^involution(x)  { |dual_tf| is |dual_theta|-stable }
  then (rho_corr,dLR) { correct the change of rho_check implicit in dual_tf }
    = fixed_lift(dual_theta-1,rho(root_datum(p))-rho(integrality_datum(p)))
  , (simple_ims,)=
       simple_system_from_positive(imaginary_sys(dual_int_ic,dual_theta))
  then phi = dual_tf + rho_corr { dual_theta stable rep.tive of dual square }
  in KGB_elt(dual_int_ic,dual_theta
            ,phi+integral_shift(rho_corr-rho_r(x),simple_ims,dLR))

dual_shift

L151dual_shift (RootDatum rd, ratvec gamma) = ratvec
amount added to central_cocharacter(G) to get dual infinitesimal character
Finding the value lambda for the dual parameter to p is surprisingly simple.
Since imaginary roots are automatically integral, there is no difference
of rho_i values to compensate for. The dual infinitesimal character is
central_cocharacter(G)+dual_shift(G,gamma), but here rho_check(G) cancels
out, giving base_grading_vector(G) + rho_check(integrality_datum(p)).
L154

ell

L162ell (KGBElt x) = vec
integral coweight associated to KGB element: is lambda-rho on dual side

dual_gamma

L167dual_gamma (Param p) = ratvec
value that can serve as g; is guaranteed to be strictly integrally dominant

dual_lambda

L170dual_lambda (Param p) = ratvec
is mod 2: ell(p)+rho(dual_inner_class)

check_dual_lambda

L173check_dual_lambda (Param p) = bool

dual 4 overloads

L177dual (Param p, InnerClass dual_integral_class) = Param
the following function used to be called |dual_alt|
L181dual(Param p) = Param
the dual_integral_class is given by dual_inner_class@Param (parameters.at)
L184dual(KGBElt x,KGBElt y, ratvec gamma) = Param
define dual of (x,y,gamma), see parameters.at
L186dual(KGBElt x,KGBElt y) = Param

also defined in hodge_K_type_formula.at, hodge_tensor.at, twisted_root_datum.at

Commented-out code, lines 188–196 (8 lines)
caution: these three functions build an inner class on the fly; if called
  multiple times even with the same argument, the results will be incompatible

  since people tend to not read the notice and get burnt anyway, just disable:

set y_alt (Param p) = KGBElt: dual_KGB(p,dual_inner_class(p))
set dual_real_form (Param p) = RealForm: real_form(y_alt(p))
set dual_alt (Param p) = Param: dual_alt(p,dual_inner_class(p))

test1

L198test1 (Param p) = [bool]
consistency of dual real form across block

test2

L202test2 (Param p) = [bool]
consistency of cocharacter across block

some indicator functions L208

support_dual

L214support_dual(KGBElt x) = [int]
support(x): those simple reflections occurring in x.w, see parabolics.at
dual_support(x): simple reflections occurring in x.w*w_0
this is the support of any y for which (x,y) is a valid parameter
integral case first

also in this file at line 222; also defined in parabolics.at, nilpotent_orbits.at

support_dual_int

L217support_dual_int(Param p) = [int]

support_dual

L222support_dual(Param p) = [int]
general case: need to replace x.w with an element of W(rd_int)

also in this file at line 214; also defined in parabolics.at, nilpotent_orbits.at

is_dual_Aq_int

L229is_dual_Aq_int(Param p) = bool
dual is an Aq(finite dimensional), regular integral case

is_dual_Aq_temp

L236is_dual_Aq_temp(Param p) = bool
dual is an Aq(finite dimensional), regular but not necessarily integral
this function is NOT reliable

is_dual_Aq 3 overloads

L242is_dual_Aq (Param p) = bool
old version, fails with an error for SU(3,2) without
the is_integral statement
L249is_dual_Aq([Param] cell) = bool
usually used to see if the dual of a cell has an Aq,
although the argument isn't required to be a cell
L252is_dual_Aq([Param] block,WCell cell) = bool
argument is a block of parameters, and a WCell

star

L256star(bool value) = string

also defined in sommers.at

Generated from atlas-scripts at commit 648506c (2026-10-13).