7 use "factorization-coords"
14 Given minor coords for { h1, h2, h3, u }, return the interior
15 coordinates of T_Q. The ordering is by column, then by
16 coxeter element: if c = { 2, 1, 3, 4} and T is the result,
19 T[0] = v2;1, T[1] = v1;1, T[2] = v3;1, T[3] = v4;1,
20 T[4] = v2;2, T[5] = v1;2, T[6] = v3;2, T[7] = v4;2,
24 const apply_M : (kc : KC_type, alpha : conf_3_star#, d_class : Dynkin_automorphism_class -> std.result((T_Q#, Dynkin_automorphism_class), byte[:]))
25 const unapply_M : (kc : KC_type, TQ : T_Q#, d_class : Dynkin_automorphism_class -> std.result((conf_3_star#, Dynkin_automorphism_class), byte[:]))
27 /* The above, but for use with the flip */
28 const apply_Mdv : (kc : KC_type, alpha : (conf_3_star#, conf_3_star#) -> std.result(T_Q02#, byte[:]))
29 const apply_Mdh : (kc : KC_type, alpha : (conf_3_star#, conf_3_star#) -> std.result(T_Q13#, byte[:]))
30 const unapply_Mdv : (kc : KC_type, TQ : T_Q13# -> std.result((conf_3_star#, conf_3_star#), byte[:]))
31 const unapply_Mdh : (kc : KC_type, TQ : T_Q13# -> std.result((conf_3_star#, conf_3_star#), byte[:]))
41 `TQ_v (weyl_reflection, int)
48 This is to eliminate redundancy in apply_M and unapply_M.
50 const alpha_TQ_bijection = {kc : KC_type, d_class : Dynkin_automorphism_class
51 var mapping : (in_alpha, in_TQ)[:] = [][:]
54 match get_sigmaG_permutation(kc)
55 | `std.Ok perm: sigmaG = perm
56 | `std.Err e: -> `std.Err std.fmt("get_sigmaG_permutation({}): {}", kc, e)
60 var c : weyl_reflection[:] = [][:]
61 var h = coxeter_num(kc)
63 var triv = trivial(d_class)
64 match get_coxeter_elt(kc)
66 | `std.Err e: -> `std.Err std.fmt("get_coxeter_elt({}): {}", kc, e)
69 for var j = 0; j < rank; ++j
70 var jz = (j + 1 : int)
71 var sgjz = (sigmaG[jz] : int)
72 var jw = (j + 1 : weyl_reflection)
74 std.slpush(&mapping, (`alpha_h1(triv ? jz : jz ), `TQ_A(triv ? jw : jw)))
75 std.slpush(&mapping, (`alpha_h2(triv ? jz : jz ), `TQ_B(triv ? jw : jw)))
76 std.slpush(&mapping, (`alpha_h3(triv ? jz : jz ), `TQ_C(triv ? sgjw : jw)))
80 Δ^{γ_1}(u) = our_u[0] should correspond to vname(c[0], 1)
82 Δ^{γ_2}(u) = our_u[1] should correspond to vname(c[1], 1)
87 for var j = 1; j <= l; ++j
90 std.slpush(&mapping, (`alpha_u(k), `TQ_v(triv ? i : i, j)))
98 const apply_M = {kc : KC_type, alpha : conf_3_star#, d_class : Dynkin_automorphism_class
99 var ret : T_Q = [ .A = [][:], .B = [][:], .C = [][:], .v = [][:] ]
102 The general formula is that, for
108 vij = Δ^{γ_k}(y) · YYYYYYYYYYY
111 var zrank = (get_n(kc) : std.size)
113 var h = coxeter_num(kc)
116 /* Just double-check alpha */
117 var fc_h1 = [][:], fc_h2 = [][:], fc_h3 = [][:]
118 match edge_fc_from_mc(kc, alpha.h1)
119 | `std.Ok f: fc_h1 = f
121 auto (e : t.doomed_str)
122 -> `std.Err std.fmt("edge_fc_from_mc(h1): {}", e)
124 match edge_fc_from_mc(kc, alpha.h2)
125 | `std.Ok f: fc_h2 = f
127 auto (e : t.doomed_str)
128 -> `std.Err std.fmt("edge_fc_from_mc(h2): {}", e)
130 match edge_fc_from_mc(kc, alpha.h3)
131 | `std.Ok f: fc_h3 = f
133 auto (e : t.doomed_str)
134 -> `std.Err std.fmt("edge_fc_from_mc(h3): {}", e)
140 if alpha.u.len == w0.len - zrank
142 elif alpha.u.len == w0.len
143 our_u = alpha.u[zrank:]
145 -> `std.Err std.fmt("alpha.u.len = {}, should be {}", alpha.u.len, w0.len - zrank)
149 match alpha_TQ_bijection(kc, d_class)
151 auto (e : t.doomed_str)
152 -> `std.Err std.fmt("alpha_TQ_bijection: {}", e)
153 | `std.Ok lmapping: mapping = lmapping
156 /* Construct T_Q return value */
157 ret.A = std.slalloc(zrank + 1)
158 ret.B = std.slalloc(zrank + 1)
159 ret.C = std.slalloc(zrank + 1)
160 for var j = 0; j <= zrank; ++j
161 ret.A[j] = yakmo.gid()
162 ret.B[j] = yakmo.gid()
163 ret.C[j] = yakmo.gid()
166 ret.v = std.slalloc(zrank + 1)
167 for var i = 0; i < ret.v.len; ++i
168 ret.v[i] = std.slalloc((l + 1 : std.size))
169 for var j = 0; j < ret.v[i].len; ++j
170 ret.v[i][j] = yakmo.gid()
174 /* Assign via bijection we constructed earlier */
175 for (ina, intq) : mapping
178 | `alpha_u (k): rf = t.dup(our_u[k].c)
179 | `alpha_h1 (k): rf = std.get(chi(fc_h1, (k : weyl_reflection)))
180 | `alpha_h2 (k): rf = std.get(chi(fc_h2, (k : weyl_reflection)))
181 | `alpha_h3 (k): rf = std.get(chi(fc_h3, (k : weyl_reflection)))
186 __dispose__(ret.v[i][j])
189 __dispose__(ret.A[j])
192 __dispose__(ret.B[j])
195 __dispose__(ret.C[j])
200 /* ... and apply monomial */
201 match just_monomial_part(kc, &ret, d_class)
203 | `std.Err e: -> `std.Err e
206 -> `std.Ok (std.mk(ret), d_class)
210 const unapply_M = {kc : KC_type, TQ_orig : T_Q#, d_class : Dynkin_automorphism_class
211 var TQ = t.dup(TQ_orig)
215 var zrank = (get_n(kc) : std.size)
217 var h = coxeter_num(kc)
220 /* Double-check T_Q */
221 if TQ.A.len != zrank + 1
222 -> `std.Err std.fmt("TQ.A.len = {}, should be {}", TQ.A.len, zrank + 1)
223 elif TQ.B.len != zrank + 1
224 -> `std.Err std.fmt("TQ.B.len = {}, should be {}", TQ.B.len, zrank + 1)
225 elif TQ.C.len != zrank + 1
226 -> `std.Err std.fmt("TQ.C.len = {}, should be {}", TQ.C.len, zrank + 1)
227 elif TQ.v.len != zrank + 1
228 -> `std.Err std.fmt("TQ.v.len = {}, should be {}", TQ.v.len, zrank + 1)
231 for var j = 0; j < TQ.v.len; ++j
232 if TQ.v[j].len != l + 1
233 -> `std.Err std.fmt("TQ.v[{}].len = {}, should be {}", j, TQ.v[j].len, l + 1)
238 match alpha_TQ_bijection(kc, d_class)
240 auto (e : t.doomed_str)
241 -> `std.Err std.fmt("alpha_TQ_bijection: {}", e)
242 | `std.Ok lmapping: mapping = lmapping
245 /* Construct conf_3_star return value */
246 var alpha : conf_3_star = [
250 /* Remember, TQ.v is padded strangely so that it can be 1-based */
251 .u = std.slalloc(w0.len - zrank),
254 for var k = 0; k < w0.len - zrank; ++k
255 alpha.u[k] = [ .k = (zrank + k + 1 : int), .c = yakmo.gid() ]
258 var fc_h1 : factorization_coordinate[:] = [][:]
259 var fc_h2 : factorization_coordinate[:] = [][:]
260 var fc_h3 : factorization_coordinate[:] = [][:]
263 To apply the monomial map in reverse, we temporarily invert
264 all edge coordinates, then apply the normal monomial map.
267 match just_monomial_part(kc, TQ, d_class)
269 | `std.Err e: -> `std.Err e
274 /* Assign via bijection we constructed earlier */
275 for (ina, intq) : mapping
278 | `TQ_v (i, j): rf = TQ.v[i][j]
279 | `TQ_A (j): rf = TQ.A[j]
280 | `TQ_B (j): rf = TQ.B[j]
281 | `TQ_C (j): rf = TQ.C[j]
286 __dispose__(alpha.u[k].c)
287 alpha.u[k].c = t.dup(rf)
288 yakmo.reduceratfunc(alpha.u[k].c)
289 | `alpha_h1 (k): std.slpush(&fc_h1, `H((k : weyl_reflection), t.dup(rf)))
290 | `alpha_h2 (k): std.slpush(&fc_h2, `H((k : weyl_reflection), t.dup(rf)))
291 | `alpha_h3 (k): std.slpush(&fc_h3, `H((k : weyl_reflection), t.dup(rf)))
298 match edge_mc_from_fc(kc, fc_h1)
299 | `std.Ok mc: alpha.h1 = mc
301 auto (e : t.doomed_str)
302 -> `std.Err std.fmt("edge_mc_from_fc(h1): {}", e)
304 match edge_mc_from_fc(kc, fc_h2)
305 | `std.Ok mc: alpha.h2 = mc
307 auto (e : t.doomed_str)
308 -> `std.Err std.fmt("edge_mc_from_fc(h2): {}", e)
310 match edge_mc_from_fc(kc, fc_h3)
311 | `std.Ok mc: alpha.h3 = mc
313 auto (e : t.doomed_str)
314 -> `std.Err std.fmt("edge_mc_from_fc(h3): {}", e)
317 match fill_in_alpha(kc, &alpha)
319 | `std.Err e: -> `std.Err std.fmt("fill_in_alpha: {}", e)
322 -> `std.Ok (std.mk(alpha), d_class)
325 const invert_edges = {kc, TQ : T_Q#
326 var new_A = std.slalloc(TQ.A.len)
327 var new_B = std.slalloc(TQ.B.len)
328 var new_C = std.slalloc(TQ.C.len)
330 for var j = 0; j < TQ.A.len; ++j
331 match yakmo.finv(TQ.A[j])
332 | `std.Some y: new_A[j] = y
333 | `std.None: new_A[j] = t.dup(TQ.A[j])
337 for var j = 0; j < TQ.B.len; ++j
338 match yakmo.finv(TQ.B[j])
339 | `std.Some y: new_B[j] = y
340 | `std.None: new_B[j] = t.dup(TQ.B[j])
344 for var j = 0; j < TQ.C.len; ++j
345 match yakmo.finv(TQ.C[j])
346 | `std.Some y: new_C[j] = y
347 | `std.None: new_C[j] = t.dup(TQ.C[j])
360 This applies the monomial part of M, in place, to TQ. It's split out
361 in order that we can use the dumb inversion trick to invert M and
362 keep the complicated w_k-fiddling in one spot.
364 const just_monomial_part = {kc : KC_type, TQ : T_Q#, d_class : Dynkin_automorphism_class
366 match get_sigmaG_permutation(kc)
367 | `std.Ok perm: sigmaG = perm
368 | `std.Err e: -> `std.Err std.fmt("get_sigmaG_permutation({}): {}", kc, e)
372 var zrank : std.size = (rank : std.size)
373 var c : weyl_reflection[:] = [][:]
374 var h = coxeter_num(kc)
377 match get_coxeter_elt(kc)
379 | `std.Err e: -> `std.Err std.fmt("get_coxeter_elt({}): {}", kc, e)
382 var one : yakmo.polynomial# = yakmo.rid()
385 var fc_sigmaGh1 : factorization_coordinate[:] = std.slalloc(zrank)
386 var fc_h2 : factorization_coordinate[:] = std.slalloc(zrank)
387 var fc_sigmaGh1_inv : factorization_coordinate[:] = std.slalloc(zrank)
388 for var j = 0; j < rank; ++j
389 var sigmaj = inv_coxeter(kc, sigmaG[c[j]])
391 match yakmo.finv(TQ.A[sigmaG[c[j]]])
392 | `std.None: -> `std.Err std.fmt("cannot invert A[{}] = {}", sigmaG[c[j]], TQ.A[sigmaG[c[j]]])
394 fc_sigmaGh1_inv[j] = `H(c[j], y)
397 fc_sigmaGh1[j] = `H((c[j] : weyl_reflection), t.dup(TQ.A[sigmaG[c[j]]]))
398 fc_h2[j] = `H((c[j] : weyl_reflection), t.dup(TQ.B[c[j]]))
402 w_k^{-1} = Length (w0.len - k + 1) prefix of w0^{-1}, backwards
403 = Length (w0.len - k + 1) suffix of w0, forwards
407 for var k = w0.len; k > rank; --k
408 match apply_wk(kc, k, fc_sigmaGh1, +1)
409 | `std.Err e: -> `std.Err std.fmt("apply_wk(k={}) : {}", k, e)
413 We can't reach directly into fc_XYZ here: the
414 H elements all commute, and applying the word
415 may have re-ordered them or (in pathological
416 cases) eliminated them.
418 match chi(loc_h1, w0[k - 1])
420 auto (x : yakmo.ratfunc#)
421 yakmo.rmul_ip(TQ.v[c[vi]][vj], x)
425 match chi(fc_sigmaGh1_inv, w0[k - 1])
427 auto (x : yakmo.ratfunc#)
428 yakmo.rmul_ip(TQ.v[c[vi]][vj], x)
432 match chi(fc_h2, w0[k - 1])
434 auto (x : yakmo.ratfunc#)
435 yakmo.rmul_ip(TQ.v[c[vi]][vj], x)
439 yakmo.reduceratfunc(TQ.v[c[vi]][vj])
452 const apply_Mdv = {kc, alpha
454 var h = coxeter_num(kc)
456 var alpha_left = alpha.0
457 var alpha_right = alpha.1
460 match apply_M(kc, alpha_left, get_trivial_Dynkin_automorphism(kc))
461 | `std.Ok (q, _): T_Q_left = q
462 | `std.Err e: -> `std.Err std.fmt("apply_M(left): {}", e)
467 match apply_M(kc, alpha_right, get_trivial_Dynkin_automorphism(kc))
468 | `std.Ok (q, _): T_Q_right = q
469 | `std.Err e: -> `std.Err std.fmt("apply_M(right): {}", e)
473 /* Make sure the two agree on the joining edge */
474 for var j = 0; j < T_Q_left.C.len; ++j
475 if !std.eq(T_Q_left.C[j], T_Q_right.A[j])
476 -> `std.Err std.fmt("cannot amalgamate: left.C = {}, right.A = {}", T_Q_left.C, T_Q_right.A)
481 var D = std.slalloc(T_Q_left.A.len)
482 for var j = 0; j < T_Q_left.A.len; ++j
483 D[j] = t.dup(T_Q_left.A[j])
486 var E = std.slalloc(T_Q_left.B.len)
487 for var j = 0; j < T_Q_left.B.len; ++j
488 E[j] = t.dup(T_Q_left.B[j])
491 var F = std.slalloc(T_Q_right.B.len)
492 for var j = 0; j < T_Q_right.B.len; ++j
493 F[j] = t.dup(T_Q_right.B[j])
496 var G = std.slalloc(T_Q_right.C.len)
497 for var j = 0; j < T_Q_right.C.len; ++j
498 G[j] = t.dup(T_Q_right.C[j])
501 var w = std.slalloc(T_Q_left.v.len)
503 for var j = 0; j < w.len; ++j
504 w[j] = std.slalloc((L + 1 : std.size))
505 w[j][0] = yakmo.rid()
507 for var k = 1; k <= l; ++k
508 w[j][k] = t.dup(T_Q_right.v[j][k])
511 w[j][l + 1] = t.dup(T_Q_right.A[j])
513 for var k = 1; k <= l; ++k
514 w[j][l + 1 + k] = t.dup(T_Q_left.v[j][k])
525 -> `std.Ok std.mk(ret)
528 const apply_Mdh = {kc, alpha
530 var h = coxeter_num(kc)
532 var alpha_top = alpha.0
533 var alpha_bottom = alpha.1
534 var d = get_trivial_Dynkin_automorphism(kc)
537 match apply_M(kc, alpha_top, d)
538 | `std.Ok (q, _): T_Q_top = q
539 | `std.Err e: -> `std.Err std.fmt("apply_M(top): {}", e)
544 match apply_M(kc, alpha_bottom, d)
545 | `std.Ok (q, _): T_Q_bottom = q
546 | `std.Err e: -> `std.Err std.fmt("apply_M(bottom): {}", e)
550 /* Make sure the two agree on the joining edge */
551 for var j = 0; j < T_Q_top.C.len; ++j
552 if !std.eq(T_Q_top.C[j], T_Q_bottom.B[j])
553 -> `std.Err std.fmt("cannot amalgamate: top.C = {}, bottom.B = {}", T_Q_top.C, T_Q_bottom.B)
558 var D = std.slalloc(T_Q_bottom.A.len)
559 for var j = 0; j < T_Q_bottom.A.len; ++j
560 D[j] = t.dup(T_Q_bottom.A[j])
563 var E = std.slalloc(T_Q_top.A.len)
564 for var j = 0; j < T_Q_top.A.len; ++j
565 E[j] = t.dup(T_Q_top.A[j])
568 var F = std.slalloc(T_Q_top.B.len)
569 for var j = 0; j < T_Q_top.B.len; ++j
570 F[j] = t.dup(T_Q_top.B[j])
573 var G = std.slalloc(T_Q_bottom.C.len)
574 for var j = 0; j < T_Q_bottom.C.len; ++j
575 G[j] = t.dup(T_Q_bottom.C[j])
578 var w = std.slalloc(T_Q_top.v.len)
580 for var j = 0; j < w.len; ++j
581 w[j] = std.slalloc((L + 1 : std.size))
582 w[j][0] = yakmo.rid()
584 for var k = 1; k <= l; ++k
585 w[j][k] = t.dup(T_Q_top.v[j][k])
588 w[j][l + 1] = t.dup(T_Q_top.C[j])
590 for var k = 1; k <= l; ++k
591 w[j][l + 1 + k] = t.dup(T_Q_bottom.v[j][k])
602 -> `std.Ok std.mk(ret)
605 const unapply_Mdv = {kc : KC_type, TQ_orig : T_Q13#
607 var h = coxeter_num(kc)
610 var middle = std.slalloc((rank + 1 : std.size))
611 for var j = 0; j <= rank; ++j
612 middle[j] = TQ_orig.w[j][l + 1]
615 var v_left = std.slalloc((rank + 1 : std.size))
616 var v_right = std.slalloc((rank + 1 : std.size))
617 for var j = 0; j <= rank; ++j
618 v_left[j] = TQ_orig.w[j][l + 1:L + 1]
619 v_right[j] = TQ_orig.w[j][0:l + 1]
636 var d = get_trivial_Dynkin_automorphism(kc)
639 match (unapply_M(kc, &TQ_left, d), unapply_M(kc, &TQ_right, d))
640 | (`std.Err e, _): ret = `std.Err std.fmt("unapply_M(left): {}", e)
641 | (_, `std.Err e): ret = `std.Err std.fmt("unapply_M(right): {}", e)
642 | (`std.Ok (aleft, _), `std.Ok (aright, _)):
643 ret = `std.Ok (aleft, aright)
653 const unapply_Mdh = {kc : KC_type, TQ_orig : T_Q13#
655 var h = coxeter_num(kc)
658 var d = get_trivial_Dynkin_automorphism(kc)
659 var middle = std.slalloc((rank + 1 : std.size))
660 for var j = 0; j <= rank; ++j
661 middle[j] = TQ_orig.w[j][l + 1]
664 var v_top = std.slalloc((rank + 1 : std.size))
665 var v_bottom = std.slalloc((rank + 1 : std.size))
666 for var j = 0; j <= rank; ++j
667 /* My apologies for the 1/l/Ls here */
669 TODO: top and bottom might need to be flipped. This
670 might also affect rename_according_to_muflip
672 v_top[j] = TQ_orig.w[j][0:l + 1]
673 v_bottom[j] = TQ_orig.w[j][l + 1:L + 1]
691 match (unapply_M(kc, &TQ_top, d), unapply_M(kc, &TQ_bottom, d))
692 | (`std.Err e, _): ret = `std.Err std.fmt("unapply_M(top): {}", e)
693 | (_, `std.Err e): ret = `std.Err std.fmt("unapply_M(bottom): {}", e)
694 | (`std.Ok (atop, _), `std.Ok (abottom, _)): ret = `std.Ok (atop, abottom)