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.
Definitions in source order
fixed_lift
L59
fixed_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
L87
integral_shift (ratvec v, mat simples,(vec d,mat L,mat R)) = vecWhen 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_classL103
dual_KGB
L112
dual_KGB (Param p, InnerClass dual_int_ic) = KGBEltcentral_cocharacter
L147
central_cocharacter (RealForm G) = ratvecset 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
L151
dual_shift (RootDatum rd, ratvec gamma) = ratvecamount 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
L162
ell (KGBElt x) = vecintegral coweight associated to KGB element: is lambda-rho on dual side
dual_gamma
L167
dual_gamma (Param p) = ratvecvalue that can serve as g; is guaranteed to be strictly integrally dominant
dual_lambda
L170
dual_lambda (Param p) = ratvecis mod 2: ell(p)+rho(dual_inner_class)
check_dual_lambda
L173
check_dual_lambda (Param p) = booldual 4 overloads
L177
dual (Param p, InnerClass dual_integral_class) = Paramthe following function used to be called |dual_alt|
L181
dual(Param p) = Paramthe dual_integral_class is given by dual_inner_class@Param (parameters.at)
L184
dual(KGBElt x,KGBElt y, ratvec gamma) = Paramdefine dual of (x,y,gamma), see parameters.at
L186
dual(KGBElt x,KGBElt y) = Paramalso 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
L198
test1 (Param p) = [bool]consistency of dual real form across block
test2
L202
test2 (Param p) = [bool]consistency of cocharacter across block
some indicator functions L208
support_dual
L214
support_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
L217
support_dual_int(Param p) = [int]support_dual
L222
support_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
L229
is_dual_Aq_int(Param p) = booldual is an Aq(finite dimensional), regular integral case
is_dual_Aq_temp
L236
is_dual_Aq_temp(Param p) = booldual is an Aq(finite dimensional), regular but not necessarily integral
this function is NOT reliable
is_dual_Aq 3 overloads
L242
is_dual_Aq (Param p) = boolold version, fails with an error for SU(3,2) without the is_integral statement
L249
is_dual_Aq([Param] cell) = boolusually used to see if the dual of a cell has an Aq, although the argument isn't required to be a cell
L252
is_dual_Aq([Param] block,WCell cell) = boolargument is a block of parameters, and a WCell
star
L256
star(bool value) = stringalso defined in sommers.at
Generated from atlas-scripts at commit 648506c (2026-10-13).
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