Ticket #14141: trac_14141reviewfs.patch
File trac_14141reviewfs.patch, 59.4 KB (added by , 8 years ago) 


sage/combinat/all.py
# HG changeset patch # User Franco Saliola <saliola@gmail.com> # Date 1368495762 14400 # Node ID 16c3277ad4c1699b97852c96c0bc4dfc50eae2ae # Parent 7ef5b208a82072db11f3cdd5a13d6d4ba90a198f imported patch trac_14141reviewfs.patch diff git a/sage/combinat/all.py b/sage/combinat/all.py
a b from cyclic_sieving_phenomenon import Cy 134 134 from sidon_sets import sidon_sets 135 135 136 136 # Puzzles 137 from knutson_tao_puzzles import PuzzlePiece, PuzzlePieces,PuzzleSolver137 from knutson_tao_puzzles import KnutsonTaoPuzzleSolver 138 138 139 139 # GelfandTsetlin patterns 140 140 from gelfand_tsetlin_patterns import GelfandTsetlinPattern, GelfandTsetlinPatterns 
sage/combinat/knutson_tao_puzzles.py
diff git a/sage/combinat/knutson_tao_puzzles.py b/sage/combinat/knutson_tao_puzzles.py
a b 1 1 r""" 2 2 KnutsonTao Puzzles 3 3 4 5 OVERVIEW OF CURRENT USAGE 6 ========================= 7 8 Here are some examples on how to use the puzzle code. 9 10 Puzzle Solvers 11  12 13 Solving and plotting puzzles:: 14 15 sage: from sage.combinat.knutson_tao_puzzles import H_grassmannian_pieces 16 sage: ps = PuzzleSolver(H_grassmannian_pieces()) 17 sage: solns = ps('0101', '0101') 18 sage: sorted(solns, key=str) 19 [{(1, 2): 1/\0 0\/1, (1, 3): 0/\0 0\/0, (3, 3): 1/1\1, (4, 4): 10/0\1, (1, 4): 1/\0 0\/1, 20 (1, 1): 0/0\0, (2, 3): 0/\10 1\/1, (2, 2): 1/1\1, (3, 4): 0/\0 1\/10, (2, 4): 1/\1 10\/0}, 21 {(1, 2): 1/\1 10\/0, (1, 3): 0/\0 1\/10, (3, 3): 0/0\0, (4, 4): 1/1\1, (1, 4): 1/\0 0\/1, 22 (1, 1): 0/1\10, (2, 3): 10/\1 0\/0, (2, 2): 0/0\0, (3, 4): 1/\0 0\/1, (2, 4): 1/\1 1\/1}] 23 sage: ps.plot(solns) # not tested 24 25 Equivariant puzzles:: 26 27 sage: from sage.combinat.knutson_tao_puzzles import HT_grassmannian_pieces 28 sage: ps = PuzzleSolver(HT_grassmannian_pieces()) 29 sage: solns = ps('0101', '0101') 30 sage: sorted(solns, key=str) 31 [{(1, 2): 1/\0 0\/1, (1, 3): 0/\0 0\/0, (3, 3): 0/0\0, (4, 4): 1/1\1, (1, 4): 1/\0 0\/1, 32 (1, 1): 0/0\0, (2, 3): 0/\1 1\/0, (2, 2): 1/1\1, (3, 4): 1/\0 0\/1, (2, 4): 1/\1 1\/1}, 33 {(1, 2): 1/\0 0\/1, (1, 3): 0/\0 0\/0, (3, 3): 1/1\1, (4, 4): 10/0\1, (1, 4): 1/\0 0\/1, 34 (1, 1): 0/0\0, (2, 3): 0/\10 1\/1, (2, 2): 1/1\1, (3, 4): 0/\0 1\/10, (2, 4): 1/\1 10\/0}, 35 {(1, 2): 1/\1 10\/0, (1, 3): 0/\0 1\/10, (3, 3): 0/0\0, (4, 4): 1/1\1, (1, 4): 1/\0 0\/1, 36 (1, 1): 0/1\10, (2, 3): 10/\1 0\/0, (2, 2): 0/0\0, (3, 4): 1/\0 0\/1, (2, 4): 1/\1 1\/1}] 37 sage: ps.plot(solns) # not tested 38 39 KTheory puzzles:: 40 41 sage: from sage.combinat.knutson_tao_puzzles import K_grassmannian_pieces 42 sage: ps = PuzzleSolver(K_grassmannian_pieces()) 43 sage: solns = ps('0101', '0101') 44 sage: sorted(solns, key=str) 45 [{(1, 2): 1/\0 0\/1, (1, 3): 0/\0 0\/0, (3, 3): 1/1\1, (4, 4): 10/0\1, (1, 4): 1/\0 0\/1, 46 (1, 1): 0/0\0, (2, 3): 0/\10 1\/1, (2, 2): 1/1\1, (3, 4): 0/\0 1\/10, (2, 4): 1/\1 10\/0}, 47 {(1, 2): 1/\1 10\/0, (1, 3): 0/\0 1\/10, (3, 3): 0/0\0, (4, 4): 1/1\1, (1, 4): 1/\0 0\/1, 48 (1, 1): 0/1\10, (2, 3): 10/\1 0\/0, (2, 2): 0/0\0, (3, 4): 1/\0 0\/1, (2, 4): 1/\1 1\/1}, 49 {(1, 2): 1/\1 10\/0, (1, 3): 0/\0 1\/K, (3, 3): 1/1\1, (4, 4): 10/0\1, (1, 4): 1/\0 0\/1, 50 (1, 1): 0/1\10, (2, 3): K/\K 0\/1, (2, 2): 0/0\0, (3, 4): 0/\0 1\/10, (2, 4): 1/\1 K\/0}] 51 sage: ps.plot(solns) # not tested 52 53 Twostep puzzles:: 54 55 sage: from sage.combinat.knutson_tao_puzzles import H_two_step_pieces 56 sage: ps = PuzzleSolver(H_two_step_pieces()) 57 sage: solns = ps('01201', '01021') 58 sage: sorted(solns, key=str) 59 [{(1, 2): 1/\0 0\/1, (1, 3): 2/\0 0\/2, (3, 3): 1/1\1, (4, 5): 20/\2 1\/10, 60 (4, 4): 1/1\1, (5, 5): 10/0\1, (1, 4): 0/\0 0\/0, (1, 1): 0/0\0, (1, 5): 1/\0 0\/1, 61 (2, 3): 2/\2 21\/1, (2, 2): 1/2\21, (2, 5): 1/\1 10\/0, (3, 4): 21/\2 1\/1, 62 (2, 4): 0/\10 2\/21, (3, 5): 0/\0 2\/20}, 63 {(1, 2): 1/\1 10\/0, (1, 3): 2/\1 1\/2, (3, 3): 0/0\0, (4, 5): 2(10)/\2 0\/1, 64 (4, 4): 0/0\0, (5, 5): 1/1\1, (1, 4): 0/\0 1\/10, (1, 1): 0/1\10, (1, 5): 1/\0 0\/1, 65 (2, 3): 2/\2 20\/0, (2, 2): 0/2\20, (2, 5): 1/\1 1\/1, (3, 4): 20/\2 0\/0, 66 (2, 4): 10/\1 2\/20, (3, 5): 1/\0 2\/2(10)}, 67 {(1, 2): 1/\21 20\/0, (1, 3): 2/\2 21\/1, (3, 3): 1/1\1, (4, 5): 21/\2 1\/1, 68 (4, 4): 10/0\1, (5, 5): 1/1\1, (1, 4): 0/\0 2\/20, (1, 1): 0/2\20, (1, 5): 1/\0 0\/1, 69 (2, 3): 1/\0 0\/1, (2, 2): 0/0\0, (2, 5): 1/\1 2\/21, (3, 4): 0/\0 1\/10, (2, 4): 20/\2 0\/0, 70 (3, 5): 21/\0 0\/21}] 71 sage: ps.plot(solns) # not tested 72 73 Twostep equivariant puzzles:: 74 75 sage: from sage.combinat.knutson_tao_puzzles import HT_two_step_pieces 76 sage: ps = PuzzleSolver(HT_two_step_pieces()) 77 sage: solns = ps('10212', '12012') 78 sage: sorted(solns, key=str) 79 [{(1, 2): 0/\(21)0 1\/2, (1, 3): 2/\1 (21)0\/0, (3, 3): 0/0\0, (4, 5): 1/\1 2\/21, (4, 4): 2/2\2, 80 (5, 5): 21/1\2, (1, 4): 1/\1 1\/1, (1, 1): 1/1\1, (1, 5): 2/\1 1\/2, (2, 3): 0/\2 2\/0, (2, 2): 2/2\2, 81 (2, 5): 2/\2 21\/1, (3, 4): 2/\0 0\/2, (2, 4): 1/\21 2\/2, (3, 5): 1/\0 0\/1}, 82 {(1, 2): 0/\(21)0 1\/2, (1, 3): 2/\1 (21)0\/0, (3, 3): 0/0\0, (4, 5): 2/\1 1\/2, (4, 4): 1/1\1, 83 (5, 5): 2/2\2, (1, 4): 1/\1 1\/1, (1, 1): 1/1\1, (1, 5): 2/\1 1\/2, (2, 3): 0/\2 2\/0, (2, 2): 2/2\2, 84 (2, 5): 2/\2 2\/2, (3, 4): 1/\0 0\/1, (2, 4): 1/\2 2\/1, (3, 5): 2/\0 0\/2}, 85 {(1, 2): 0/\(21)0 1\/2, (1, 3): 2/\1 (21)0\/0, (3, 3): 2/2\2, (4, 5): 1/\1 2\/21, (4, 4): 20/0\2, 86 (5, 5): 21/1\2, (1, 4): 1/\1 1\/1, (1, 1): 1/1\1, (1, 5): 2/\1 1\/2, (2, 3): 0/\20 2\/2, (2, 2): 2/2\2, 87 (2, 5): 2/\2 21\/1, (3, 4): 0/\0 2\/20, (2, 4): 1/\21 20\/0, (3, 5): 1/\0 0\/1}, 88 {(1, 2): 0/\1 1\/0, (1, 3): 2/\1 1\/2, (3, 3): 0/0\0, (4, 5): 1/\1 2\/21, (4, 4): 2/2\2, (5, 5): 21/1\2, 89 (1, 4): 1/\1 1\/1, (1, 1): 1/1\1, (1, 5): 2/\1 1\/2, (2, 3): 2/\2 20\/0, (2, 2): 0/2\20, 90 (2, 5): 2/\2 21\/1, (3, 4): 2/\0 0\/2, (2, 4): 1/\21 2\/2, (3, 5): 1/\0 0\/1}, 91 {(1, 2): 0/\1 1\/0, (1, 3): 2/\1 1\/2, (3, 3): 0/0\0, (4, 5): 2/\1 1\/2, (4, 4): 1/1\1, 92 (5, 5): 2/2\2, (1, 4): 1/\1 1\/1, (1, 1): 1/1\1, (1, 5): 2/\1 1\/2, (2, 3): 2/\2 20\/0, 93 (2, 2): 0/2\20, (2, 5): 2/\2 2\/2, (3, 4): 1/\0 0\/1, (2, 4): 1/\2 2\/1, (3, 5): 2/\0 0\/2}, 94 {(1, 2): 0/\10 1\/1, (1, 3): 2/\10 10\/2, (3, 3): 1/1\1, (4, 5): 10/\1 2\/20, (4, 4): 2/2\2, 95 (5, 5): 20/0\2, (1, 4): 1/\1 10\/0, (1, 1): 1/1\1, (1, 5): 2/\1 1\/2, (2, 3): 2/\2 21\/1, 96 (2, 2): 1/2\21, (2, 5): 2/\2 20\/0, (3, 4): 2/\1 1\/2, (2, 4): 0/\20 2\/2, (3, 5): 0/\0 1\/10}, 97 {(1, 2): 0/\10 1\/1, (1, 3): 2/\10 10\/2, (3, 3): 1/1\1, (4, 5): 2/\1 1\/2, (4, 4): 10/0\1, 98 (5, 5): 2/2\2, (1, 4): 1/\1 10\/0, (1, 1): 1/1\1, (1, 5): 2/\1 1\/2, (2, 3): 2/\2 21\/1, 99 (2, 2): 1/2\21, (2, 5): 2/\2 2\/2, (3, 4): 0/\0 1\/10, (2, 4): 0/\2 2\/0, (3, 5): 2/\0 0\/2}, 100 {(1, 2): 0/\20 21\/1, (1, 3): 2/\2 20\/0, (3, 3): 0/0\0, (4, 5): 2/\1 1\/2, (4, 4): 1/1\1, 101 (5, 5): 2/2\2, (1, 4): 1/\1 2\/21, (1, 1): 1/2\21, (1, 5): 2/\1 1\/2, (2, 3): 0/\1 1\/0, 102 (2, 2): 1/1\1, (2, 5): 2/\2 2\/2, (3, 4): 1/\0 0\/1, (2, 4): 21/\2 1\/1, (3, 5): 2/\0 0\/2}, 103 {(1, 2): 0/\20 21\/1, (1, 3): 2/\2 20\/0, (3, 3): 1/1\1, (4, 5): 2/\1 1\/2, (4, 4): 10/0\1, 104 (5, 5): 2/2\2, (1, 4): 1/\1 2\/21, (1, 1): 1/2\21, (1, 5): 2/\1 1\/2, (2, 3): 0/\10 1\/1, 105 (2, 2): 1/1\1, (2, 5): 2/\2 2\/2, (3, 4): 0/\0 1\/10, (2, 4): 21/\2 10\/0, (3, 5): 2/\0 0\/2}, 106 {(1, 2): 0/\21 21\/0, (1, 3): 2/\2 21\/1, (3, 3): 0/0\0, (4, 5): 2/\1 1\/2, (4, 4): 1/1\1, 107 (5, 5): 2/2\2, (1, 4): 1/\1 2\/21, (1, 1): 1/2\21, (1, 5): 2/\1 1\/2, (2, 3): 1/\1 10\/0, 108 (2, 2): 0/1\10, (2, 5): 2/\2 2\/2, (3, 4): 1/\0 0\/1, (2, 4): 21/\2 1\/1, (3, 5): 2/\0 0\/2}] 109 sage: ps.plot(solns) # not tested 110 111 Structure Constants for Products 112  113 114 From the puzzles we can compute the structure coefficients in the various settings. 115 116 Grassmannian cohomology:: 117 118 sage: from sage.combinat.knutson_tao_puzzles import cohomology_product, H_grassmannian_pieces 119 sage: cohomology_product(H_grassmannian_pieces(), '0101', '0101') 120 {('1', '0', '0', '1'): 1, ('0', '1', '1', '0'): 1} 121 122 Equivariant cohomology:: 123 124 sage: from sage.combinat.knutson_tao_puzzles import cohomology_product, HT_grassmannian_pieces 125 sage: cohomology_product( HT_grassmannian_pieces(), '0101', '0101') 126 {('0', '1', '0', '1'): y2  y3, ('1', '0', '0', '1'): 1, ('0', '1', '1', '0'): 1} 127 128 Ktheory:: 129 130 sage: from sage.combinat.knutson_tao_puzzles import cohomology_product, K_grassmannian_pieces 131 sage: cohomology_product(K_grassmannian_pieces(), '0101', '0101') 132 {('1', '0', '0', '1'): 1, ('0', '1', '1', '0'): 1, ('1', '0', '1', '0'): 1} 133 134 Twostep:: 135 136 sage: from sage.combinat.knutson_tao_puzzles import cohomology_product, H_two_step_pieces 137 sage: cohomology_product(H_two_step_pieces(), '01122', '01122') 138 {('0', '1', '1', '2', '2'): 1} 139 sage: sorted(cohomology_product(H_two_step_pieces(), '01201', '01021'), key = str) 140 [('0', '2', '1', '1', '0'), 141 ('1', '2', '0', '0', '1'), 142 ('2', '0', '1', '0', '1')] 143 144 Twostep equivariant:: 145 146 sage: from sage.combinat.knutson_tao_puzzles import cohomology_product, HT_two_step_pieces 147 sage: D = cohomology_product(HT_two_step_pieces(), list('10212'), list('12012')) 148 sage: ds = sorted(D.keys(), key=str) 149 sage: dict([(p,D[p]) for p in ds]) 150 {('1', '2', '1', '0', '2'): y2  y4, ('1', '2', '0', '2', '1'): y1  y3, 151 ('1', '2', '0', '1', '2'): y1*y2  y2*y3  y1*y4 + y3*y4, ('1', '2', '1', '2', '0'): 1, 152 ('2', '1', '0', '1', '2'): y1  y3, ('1', '2', '2', '0', '1'): 1, ('2', '1', '1', '0', '2'): 1} 153 154 Algebra 155  156 157 Create the algebra and compute products:: 158 159 sage: from sage.combinat.knutson_tao_puzzles import SchubertCalculusAlgebra 160 sage: WordOptions(identifier='') 161 sage: Sc = SchubertCalculusAlgebra(QQ, (3,3)) 162 sage: x = Sc.an_element() 163 sage: x 164 2*Sc[000111] + 2*Sc[001011] + 3*Sc[001101] 165 sage: x*x 166 4*Sc[000111] + 8*Sc[001011] + 16*Sc[001101] + 12*Sc[001110] + 4*Sc[010011] + 12*Sc[010101] + 9*Sc[010110] + 9*Sc[011001] 167 168 KTheory:: 169 170 sage: from sage.combinat.knutson_tao_puzzles import SchubertCalculusAlgebra 171 sage: Sc = SchubertCalculusAlgebra(QQ, (3,3), K=True) 172 sage: x = Sc.an_element() 173 sage: x * x 174 4*Sc[000111] + 8*Sc[001011] + 16*Sc[001101] + 12*Sc[001110] + 4*Sc[010011] + 8*Sc[010101] + (3)*Sc[010110] + 9*Sc[011001] + (9)*Sc[011010] 4 This module implements a generic algorithm to solve KnutsonTao puzzles. An 5 instance of this class will be callable: the arguments are the labels of 6 northeast and northwest sides of the puzzle boundary; the output is the list 7 of the fillings of the puzzle with the specified pieces. 175 8 176 9 Acknowledgements 177 10  … … The code was tested afterwards by Liz Be 185 18 186 19  plotter will not plot edge labels higher than 2; e.g. in BK puzzles, the labels are 187 20 1,..., n and so in 3step examples, none of the edge labels with 3 appear 21 188 22  we should also have a 3step puzzle pieces constructor, taken from p22 of 189 23 {{{:arxiv:`0610538`}}} 190 24 191 Speed ups (possible):192 193  write a method that computes the the fillings of a 1 x k strip given the194 k NW labels and the single NE label; cache the results195  if the method hasn't yet computed the filling, use a recursive call to196 fill the righthand 1 x (k1) strip, and for each of those look at all197 ways to put on one more rhombus198 199 25 """ 200 26 #***************************************************************************** 201 27 # Copyright (C) 2013 Franco Saliola <saliola@gmail.com>, … … class PuzzlePieces(object): 692 518 """ 693 519 Construct a valid set of puzzle pieces. 694 520 695 This class constructs the set of valid puzzle pieces. It can take 696 a list of forbidden border labels as input. The user can add 697 valid nabla or delta pieces and specify which rotations of these 698 pieces are legal. For example, ``rotations=0`` does not add any 699 additional pieces (only the piece itself), ``rotations=60`` adds 700 six pieces (the pieces and its rotations by 60, 120, 180, 240, 300), etc.. 521 This class constructs the set of valid puzzle pieces. It can take a list of 522 forbidden border labels as input. These labels are forbidden from appearing 523 on the south edge of a puzzle filling. The user can add valid nabla or 524 delta pieces and specify which rotations of these pieces are legal. For 525 example, ``rotations=0`` does not add any additional pieces (only the piece 526 itself), ``rotations=60`` adds six pieces (the pieces and its rotations by 527 60, 120, 180, 240, 300), etc.. 701 528 702 529 EXAMPLES:: 703 530 704 sage: from sage.combinat.knutson_tao_puzzles import NablaPiece531 sage: from sage.combinat.knutson_tao_puzzles import PuzzlePieces, NablaPiece 705 532 sage: forbidden_border_labels = ['10'] 706 533 sage: pieces = PuzzlePieces(forbidden_border_labels) 707 534 sage: pieces.add_piece(NablaPiece('0','0','0'), rotations=60) … … class PuzzlePieces(object): 717 544 [0/\0 0\/0, 0/\0 1\/10, 0/\10 10\/0, 0/\10 1\/1, 1/\0 0\/1, 718 545 1/\1 10\/0, 1/\1 1\/1, 10/\1 0\/0, 10/\1 1\/10] 719 546 """ 720 721 547 def __init__(self, forbidden_border_labels=None): 722 548 """ 723 549 INPUT: … … class PuzzlePieces(object): 726 552 727 553 TESTS:: 728 554 729 sage: forbidden_border_labels = ['10'] 730 sage: pieces = PuzzlePieces(forbidden_border_labels) 731 sage: pieces 732 Nablas : [] 733 Deltas : [] 555 sage: from sage.combinat.knutson_tao_puzzles import PuzzlePieces 556 sage: forbidden_border_labels = ['10'] 557 sage: pieces = PuzzlePieces(forbidden_border_labels) 558 sage: pieces 559 Nablas : [] 560 Deltas : [] 734 561 735 sage: PuzzlePieces('10')736 Traceback (most recent call last):737 ...738 TypeError: Input must be a list562 sage: PuzzlePieces('10') 563 Traceback (most recent call last): 564 ... 565 TypeError: Input must be a list 739 566 """ 740 567 self._nabla_pieces = set([]) 741 568 self._delta_pieces = set([]) … … class PuzzlePieces(object): 790 617 791 618 EXAMPLES:: 792 619 793 sage: from sage.combinat.knutson_tao_puzzles import DeltaPiece620 sage: from sage.combinat.knutson_tao_puzzles import PuzzlePieces, DeltaPiece 794 621 sage: delta = DeltaPiece('a','b','c') 795 622 sage: pieces = PuzzlePieces() 796 623 sage: pieces … … class PuzzlePieces(object): 837 664 838 665 EXAMPLES:: 839 666 667 sage: from sage.combinat.knutson_tao_puzzles import PuzzlePieces 840 668 sage: pieces = PuzzlePieces() 841 669 sage: pieces.add_forbidden_label('1') 842 670 sage: pieces._forbidden_border_labels … … class PuzzlePieces(object): 857 685 858 686 EXAMPLES:: 859 687 688 sage: from sage.combinat.knutson_tao_puzzles import PuzzlePieces 860 689 sage: pieces = PuzzlePieces() 861 690 sage: pieces.add_T_piece('1','3') 862 691 sage: pieces … … class PuzzlePieces(object): 872 701 """ 873 702 TESTS:: 874 703 875 sage: from sage.combinat.knutson_tao_puzzles import DeltaPiece704 sage: from sage.combinat.knutson_tao_puzzles import PuzzlePieces, DeltaPiece 876 705 sage: pieces = PuzzlePieces() 877 706 sage: delta = DeltaPiece('a','b','c') 878 707 sage: pieces.add_piece(delta,rotations=60) … … class PuzzlePieces(object): 890 719 891 720 EXAMPLES:: 892 721 893 sage: from sage.combinat.knutson_tao_puzzles import DeltaPiece722 sage: from sage.combinat.knutson_tao_puzzles import PuzzlePieces, DeltaPiece 894 723 sage: pieces = PuzzlePieces() 895 724 sage: delta = DeltaPiece('a','b','c') 896 725 sage: pieces.add_piece(delta,rotations=60) … … class PuzzlePieces(object): 905 734 906 735 EXAMPLES:: 907 736 908 sage: from sage.combinat.knutson_tao_puzzles import DeltaPiece737 sage: from sage.combinat.knutson_tao_puzzles import PuzzlePieces, DeltaPiece 909 738 sage: pieces = PuzzlePieces() 910 739 sage: delta = DeltaPiece('a','b','c') 911 740 sage: pieces.add_piece(delta,rotations=60) … … class PuzzlePieces(object): 923 752 924 753 EXAMPLES:: 925 754 926 sage: from sage.combinat.knutson_tao_puzzles import DeltaPiece755 sage: from sage.combinat.knutson_tao_puzzles import PuzzlePieces, DeltaPiece 927 756 sage: pieces = PuzzlePieces() 928 757 sage: delta = DeltaPiece('a','b','c') 929 758 sage: pieces.add_piece(delta,rotations=60) … … class PuzzlePieces(object): 943 772 944 773 EXAMPLES:: 945 774 946 sage: from sage.combinat.knutson_tao_puzzles import DeltaPiece775 sage: from sage.combinat.knutson_tao_puzzles import PuzzlePieces, DeltaPiece 947 776 sage: pieces = PuzzlePieces(['a']) 948 777 sage: delta = DeltaPiece('a','b','c') 949 778 sage: pieces.add_piece(delta,rotations=60) … … def HT_two_step_pieces(): 1075 904 return pieces 1076 905 1077 906 1078 def BK_pieces(max Letter):907 def BK_pieces(max_letter): 1079 908 """ 1080 909 Defines the puzzle pieces used in computing the BelkaleKumar coefficients for any partial flag variety in type `A`. 1081 910 1082 911 INPUT: 1083 912 1084  ``max Letter``  positive integer specifying the number of steps in the partial flag variety913  ``max_letter``  positive integer specifying the number of steps in the partial flag variety 1085 914 1086 915 REFERENCES: 1087 916 … … def BK_pieces(maxLetter): 1095 924 Nablas : [0\0/0, 1\1/1, 2\2/2, 3\3/3] 1096 925 Deltas : [0/0\0, 1/1\1, 2/2\2, 3/3\3] 1097 926 """ 1098 max Letter += 11099 forbidden_border_labels = ['%s%s' % (i,j) for j in range(max Letter1) for i in range(j+1,maxLetter)]927 max_letter += 1 928 forbidden_border_labels = ['%s%s' % (i,j) for j in range(max_letter1) for i in range(j+1,max_letter)] 1100 929 pieces = PuzzlePieces(forbidden_border_labels) 1101 for j in range(0, maxLetter):930 for j in range(0, max_letter): 1102 931 jstr = '%s'%j 1103 932 pieces.add_piece(DeltaPiece(jstr,jstr,jstr), rotations = 60) 1104 933 1105 for i in range(j+1, maxLetter):934 for i in range(j+1, max_letter): 1106 935 istr = '%s'%i 1107 936 pieces.add_piece(DeltaPiece(istr+jstr, istr, jstr), rotations = 60) 1108 937 1109 938 return pieces 1110 939 1111 1112 def cohomology_product(pieces, lamda, mu, nu=None): 1113 r""" 1114 Compute cohomology structure coefficients from puzzles. 1115 1116 INPUT: 1117 1118  ``pieces``  puzzle pieces to be used 1119  ``lambda``, ``mu``  edge labels of puzzle for northwest and north east side 1120  ``nu``  (default: ``None``) If ``nu`` is not specified a dictionary is returned with 1121 the structure coefficients corresponding to all south labels; if ``nu`` is given, only 1122 the coefficients with the specified label is returned. 1123 1124 EXAMPLES:: 1125 1126 sage: from sage.combinat.knutson_tao_puzzles import cohomology_product, H_grassmannian_pieces, HT_grassmannian_pieces 1127 sage: sorted(cohomology_product(H_grassmannian_pieces(), '0101', '0101').items(), key = str) 1128 [(('0', '1', '1', '0'), 1), (('1', '0', '0', '1'), 1)] 1129 sage: sorted(cohomology_product(HT_grassmannian_pieces(), '0101', '0101').items(), key = str) 1130 [(('0', '1', '0', '1'), y2  y3), 1131 (('0', '1', '1', '0'), 1), 1132 (('1', '0', '0', '1'), 1)] 1133 1134 sage: cohomology_product(H_grassmannian_pieces(), '001001', '001010', '010100') 1135 1 1136 """ 1137 ps = PuzzleSolver(pieces) 1138 from collections import defaultdict 1139 R = PolynomialRing(Integers(), 'y', len(lamda)+1) 1140 z = defaultdict(R.zero) 1141 for p in ps(list(lamda), list(mu)): 1142 z[p.south_labels()] += p.contribution() 1143 if nu is None: 1144 return dict(z) 1145 else: 1146 return z[tuple(nu)] 1147 1148 1149 class PartialPuzzle(object): 940 class PuzzleFilling(object): 1150 941 r""" 1151 942 Create partial puzzles and provides methods to build puzzles from them. 1152 943 """ … … class PartialPuzzle(object): 1154 945 """ 1155 946 TESTS:: 1156 947 1157 sage: from sage.combinat.knutson_tao_puzzles import P artialPuzzle1158 sage: P = P artialPuzzle('0101','0101')948 sage: from sage.combinat.knutson_tao_puzzles import PuzzleFilling 949 sage: P = PuzzleFilling('0101','0101') 1159 950 sage: P 1160 951 {} 1161 952 """ … … class PartialPuzzle(object): 1169 960 """ 1170 961 TESTS:: 1171 962 1172 sage: ps = PuzzleSolver("H") 963 sage: from sage.combinat.knutson_tao_puzzles import KnutsonTaoPuzzleSolver 964 sage: ps = KnutsonTaoPuzzleSolver("H") 1173 965 sage: puzzle = ps('0101','1001')[0] 1174 966 sage: puzzle 1175 967 {(1, 2): 1/\1 10\/0, (1, 3): 0/\10 1\/1, (3, 3): 1/1\1, (4, 4): 10/0\1, … … class PartialPuzzle(object): 1189 981 1190 982 EXAMPLES:: 1191 983 1192 sage: from sage.combinat.knutson_tao_puzzles import P artialPuzzle1193 sage: P = P artialPuzzle('0101','0101')984 sage: from sage.combinat.knutson_tao_puzzles import PuzzleFilling 985 sage: P = PuzzleFilling('0101','0101') 1194 986 sage: P 1195 987 {} 1196 988 sage: P.kink_coordinates() … … class PartialPuzzle(object): 1204 996 1205 997 EXAMPLES:: 1206 998 1207 sage: from sage.combinat.knutson_tao_puzzles import P artialPuzzle1208 sage: P = P artialPuzzle('0101','0101')999 sage: from sage.combinat.knutson_tao_puzzles import PuzzleFilling 1000 sage: P = PuzzleFilling('0101','0101') 1209 1001 sage: P.is_in_south_edge() 1210 1002 False 1211 1003 """ … … class PartialPuzzle(object): 1218 1010 1219 1011 EXAMPLES:: 1220 1012 1221 sage: from sage.combinat.knutson_tao_puzzles import P artialPuzzle1222 sage: P = P artialPuzzle('0101','0101')1013 sage: from sage.combinat.knutson_tao_puzzles import PuzzleFilling 1014 sage: P = PuzzleFilling('0101','0101') 1223 1015 sage: P.north_west_label_of_kink() 1224 1016 '1' 1225 1017 """ … … class PartialPuzzle(object): 1235 1027 1236 1028 EXAMPLES:: 1237 1029 1238 sage: from sage.combinat.knutson_tao_puzzles import P artialPuzzle1239 sage: P = P artialPuzzle('0101','0101')1030 sage: from sage.combinat.knutson_tao_puzzles import PuzzleFilling 1031 sage: P = PuzzleFilling('0101','0101') 1240 1032 sage: P.north_east_label_of_kink() 1241 1033 '0' 1242 1034 """ … … class PartialPuzzle(object): 1252 1044 1253 1045 EXAMPLES:: 1254 1046 1255 sage: from sage.combinat.knutson_tao_puzzles import P artialPuzzle1256 sage: P = P artialPuzzle('0101','0101')1047 sage: from sage.combinat.knutson_tao_puzzles import PuzzleFilling 1048 sage: P = PuzzleFilling('0101','0101') 1257 1049 sage: P.is_completed() 1258 1050 False 1259 1051 1260 sage: ps = PuzzleSolver("H") 1052 sage: from sage.combinat.knutson_tao_puzzles import KnutsonTaoPuzzleSolver 1053 sage: ps = KnutsonTaoPuzzleSolver("H") 1261 1054 sage: puzzle = ps('0101','1001')[0] 1262 1055 sage: puzzle.is_completed() 1263 1056 True … … class PartialPuzzle(object): 1271 1064 1272 1065 EXAMPLES:: 1273 1066 1274 sage: ps = PuzzleSolver("H") 1067 sage: from sage.combinat.knutson_tao_puzzles import KnutsonTaoPuzzleSolver 1068 sage: ps = KnutsonTaoPuzzleSolver("H") 1275 1069 sage: ps('0101','1001')[0].south_labels() 1276 1070 ('1', '0', '1', '0') 1277 1071 """ 1072 # TODO: return ''.join(self[i, i]['south'] for i in range(1, self._n + 1)) 1278 1073 return tuple([self[i,i]['south'] for i in range(1, self._n+1)]) 1279 1074 1280 1075 def add_piece(self, piece): … … class PartialPuzzle(object): 1283 1078 1284 1079 EXAMPLES:: 1285 1080 1286 sage: from sage.combinat.knutson_tao_puzzles import DeltaPiece, P artialPuzzle1081 sage: from sage.combinat.knutson_tao_puzzles import DeltaPiece, PuzzleFilling 1287 1082 sage: piece = DeltaPiece('0','1','0') 1288 sage: P = P artialPuzzle('0101','0101'); P1083 sage: P = PuzzleFilling('0101','0101'); P 1289 1084 {} 1290 1085 sage: P.add_piece(piece); P 1291 1086 {(1, 4): 1/0\0} … … class PartialPuzzle(object): 1309 1104 1310 1105 EXAMPLES:: 1311 1106 1312 sage: from sage.combinat.knutson_tao_puzzles import DeltaPiece, P artialPuzzle1313 sage: P = P artialPuzzle('0101','0101'); P1107 sage: from sage.combinat.knutson_tao_puzzles import DeltaPiece, PuzzleFilling 1108 sage: P = PuzzleFilling('0101','0101'); P 1314 1109 {} 1315 1110 sage: piece = DeltaPiece('0','1','0') 1316 1111 sage: pieces = [piece,piece] … … class PartialPuzzle(object): 1335 1130 EXAMPLES:: 1336 1131 1337 1132 1338 sage: from sage.combinat.knutson_tao_puzzles import DeltaPiece, P artialPuzzle1133 sage: from sage.combinat.knutson_tao_puzzles import DeltaPiece, PuzzleFilling 1339 1134 sage: piece = DeltaPiece('0','1','0') 1340 sage: P = P artialPuzzle('0101','0101'); P1135 sage: P = PuzzleFilling('0101','0101'); P 1341 1136 {} 1342 1137 sage: PP = P.copy() 1343 1138 sage: P.add_piece(piece); P … … class PartialPuzzle(object): 1345 1140 sage: PP 1346 1141 {} 1347 1142 """ 1348 PP = P artialPuzzle(self._nw_labels, self._ne_labels)1143 PP = PuzzleFilling(self._nw_labels, self._ne_labels) 1349 1144 PP._squares = self._squares.copy() 1350 1145 PP._kink_coordinates = self._kink_coordinates 1351 1146 PP._n = self._n … … class PartialPuzzle(object): 1357 1152 1358 1153 EXAMPLES:: 1359 1154 1360 sage: ps = PuzzleSolver("HT") 1155 sage: from sage.combinat.knutson_tao_puzzles import KnutsonTaoPuzzleSolver 1156 sage: ps = KnutsonTaoPuzzleSolver("HT") 1361 1157 sage: puzzles = ps('0101','1001') 1362 sage: sorted([p.contribution() for p in puzzles], key =str)1158 sage: sorted([p.contribution() for p in puzzles], key=str) 1363 1159 [1, y1  y3] 1364 1160 """ 1365 1161 R = PolynomialRing(Integers(), 'y', self._n+1) … … class PartialPuzzle(object): 1377 1173 """ 1378 1174 TESTS:: 1379 1175 1380 sage: from sage.combinat.knutson_tao_puzzles import H_grassmannian_pieces, P artialPuzzle1381 sage: P = P artialPuzzle('0101','0101'); P1176 sage: from sage.combinat.knutson_tao_puzzles import H_grassmannian_pieces, PuzzleFilling 1177 sage: P = PuzzleFilling('0101','0101'); P 1382 1178 {} 1383 1179 sage: P.__repr__() 1384 1180 '{}' … … class PartialPuzzle(object): 1391 1187 1392 1188 TESTS:: 1393 1189 1394 sage: ps = PuzzleSolver("H") 1190 sage: from sage.combinat.knutson_tao_puzzles import KnutsonTaoPuzzleSolver 1191 sage: ps = KnutsonTaoPuzzleSolver("H") 1395 1192 sage: puzzle = ps('0101','1001')[0] 1396 1193 sage: puzzle 1397 1194 {(1, 2): 1/\1 10\/0, (1, 3): 0/\10 1\/1, (3, 3): 1/1\1, (4, 4): 10/0\1, … … class PartialPuzzle(object): 1419 1216 1420 1217 EXAMPLES:: 1421 1218 1422 sage: ps = PuzzleSolver("H") 1219 sage: from sage.combinat.knutson_tao_puzzles import KnutsonTaoPuzzleSolver 1220 sage: ps = KnutsonTaoPuzzleSolver("H") 1423 1221 sage: puzzle = ps('0101','1001')[0] 1424 1222 sage: puzzle.plot() #not tested 1425 1223 sage: puzzle.plot(style='fill') #not tested … … class PartialPuzzle(object): 1454 1252 sage: latex.extra_preamble(r'''\usepackage{tikz}''') 1455 1253 sage: from sage.combinat.knutson_tao_puzzles import * 1456 1254 1457 sage: ps = PuzzleSolver(H_grassmannian_pieces())1255 sage: ps = KnutsonTaoPuzzleSolver(H_grassmannian_pieces()) 1458 1256 sage: solns = ps('0101', '0101') 1459 1257 sage: view(solns[0], viewer='pdf', tightpage=True) # not tested 1460 1258 1461 sage: ps = PuzzleSolver(HT_two_step_pieces())1259 sage: ps = KnutsonTaoPuzzleSolver(HT_two_step_pieces()) 1462 1260 sage: solns = ps(list('10212'), list('12012')) 1463 1261 sage: view(solns[0], viewer='pdf', tightpage=True) # not tested 1464 1262 1465 sage: ps = PuzzleSolver(K_grassmannian_pieces())1263 sage: ps = KnutsonTaoPuzzleSolver(K_grassmannian_pieces()) 1466 1264 sage: solns = ps('0101', '0101') 1467 1265 sage: view(solns[0], viewer='pdf', tightpage=True) # not tested 1468 1266 … … class PartialPuzzle(object): 1526 1324 1527 1325 return s 1528 1326 1529 def path_thru_puzzle(self, coord): 1530 """ 1531 Returns the content row of the LR skew tableau corresponding to ``coord``. 1532 1533 This method traces out a path from ``coord`` to its "mirror" coordinate. 1534 If ``coord`` specifies the `i`th 1 from the top on the northeast border 1535 of the puzzle, then its mirror is the `i`th 1 from the top on the northwest 1536 border. The algorithm records the content numbers of the traced vertical rhombi. 1537 See [Vakil03]_ and [Purbhoo07]_. 1538 1539 .. WARNING:: 1540 1541 This method only works for the classical cohomology puzzle pieces. 1542 1543 REFERENCES: 1544 1545 .. [Vakil03] R. Vakil, A geometric LittlewoodRichardson rule, {{{:arXiv:`0302294`}}} 1546 1547 .. [Purbhoo07] K. Purbhoo, Puzzles, Tableaux and Mosaics, {{{:arXiv:`0705.1184`}}} 1548 1549 INPUT: 1550 1551  ``corrd``  northeast boundary position counting from the top whose label is 1 1552 1553 OUTPUT: a list of numbers giving the content of one row in the LR tableau 1554 1555 EXAMPLES:: 1556 1557 sage: ps = PuzzleSolver("H") 1558 sage: solns = sorted(ps('0010111','0011011'), key = str) 1559 sage: puzzle = solns[0] 1560 sage: puzzle.path_thru_puzzle(6) 1561 [1, 3, 3] 1562 sage: puzzle.path_thru_puzzle(5) 1563 Traceback (most recent call last): 1564 ... 1565 AssertionError: The coordinate needs to be a coordinate of a 1 on the north east boundary 1566 1567 sage: puzzle = solns[1] 1568 sage: puzzle.path_thru_puzzle(7) 1569 [4, 4] 1570 """ 1571 i = coord 1572 assert self._ne_labels[coord1] == '1', "The coordinate needs to be a coordinate of a 1 on the north east boundary" 1573 j = self._n 1574 k = 0 1575 LR_list=[] 1576 dir = "N" 1577 while i != 0: 1578 if i==j: 1579 current_piece = self[(i,j)] 1580 current_labels = current_piece.border() 1581 if current_labels == ('1', '1', '1'): 1582 i = i1 1583 dir = "S" 1584 k = k+1 1585 elif current_labels == ('0', '10', '1'): 1586 i = i1 1587 j = j1 1588 elif dir == "N": 1589 current_piece = self[(i,j)].north_piece() 1590 current_labels = current_piece.border() 1591 if current_labels == ('1', '1', '1'): 1592 i = i1 1593 dir = "S" 1594 k = k+1 1595 elif current_labels == ('0', '10', '1'): 1596 i = i1 1597 j = j1 1598 elif dir == "S": 1599 current_piece = self[(i,j)].south_piece() 1600 current_labels = current_piece.border() 1601 if current_labels == ('1', '1', '1'): 1602 j = j1 1603 dir = "N" 1604 elif current_labels == ('10', '1', '0'): 1605 i = i1 1606 LR_list.append(k) 1607 else: #only necessary if wrong input to terminate loop! 1608 i = i1 1609 return LR_list 1610 1611 1612 def LR_tab_from_puzzle(self): 1613 """ 1614 Creates the skew LittlewoodRichardson tableau from the puzzle ``self``. 1615 1616 EXAMPLES:: 1617 1618 sage: ps = PuzzleSolver("H") 1619 sage: solns = ps('010101','010101') 1620 sage: sorted([puzzle.LR_tab_from_puzzle() for puzzle in solns]) 1621 [[[None, None, 1], [None, 1], [1]], 1622 [[None, None, 1], [None, 1], [2]], 1623 [[None, None, 1], [None, 2], [1]], 1624 [[None, None, 1], [None, 2], [3]]] 1625 """ 1626 st = self._nw_labels 1627 lam = partition_from_string(st) 1628 k = 0 1629 LRtableaux = [] 1630 for i in range(0,len(st)): 1631 LRrow = [] 1632 if st[i] == '1': 1633 k=k+1 1634 for j in range(0,lam[k1]): 1635 LRrow.append(None) 1636 LRrow.extend(self.path_thru_puzzle(i+1)) 1637 LRtableaux.append(LRrow) 1638 return SkewTableau(LRtableaux) 1639 1640 1641 def partition_from_string(str): 1642 """ 1643 Returns a partition from the string data of a partition. 1644 1645 INPUT: 1646 1647  ``str``  a tuple of a string of 1's and 0's 1648 1649 OUTPUT: 1650 1651  a list of weakly decreasing integers specifying the corresponding partition shape 1652 1653 EXAMPLES:: 1654 1655 sage: from sage.combinat.knutson_tao_puzzles import partition_from_string 1656 sage: partition_from_string(('0','1','0','1','0','1')) 1657 [2, 1, 0] 1658 sage: partition_from_string(('0','0','0','0','1','1')) 1659 [0, 0] 1660 sage: partition_from_string(('0','0','0','1','1','1')) 1661 [0, 0, 0] 1662 sage: partition_from_string(('1','1','1','0','0','0')) 1663 [3, 3, 3] 1664 """ 1665 Pt = [] 1666 n = len(str) 1667 k=0 1668 for i in range(0,n): 1669 if str[ni1]=='1': 1670 k=k+1 1671 Pt.append(i+1k) 1672 return Pt[::1] 1673 1674 class PuzzleSolver(UniqueRepresentation): 1327 class KnutsonTaoPuzzleSolver(UniqueRepresentation): 1675 1328 r""" 1676 1329 Returns puzzle solver function used to create all puzzles with given boundary conditions. 1677 1330 """ 1678 1331 def __init__(self, puzzle_pieces): 1679 1332 r""" 1680 Initialize the puzzle solver. 1333 KnutsonTao puzzle solver. 1334 1335 This class implements a generic algorithm to solve KnutsonTao puzzles. 1336 An instance of this class will be callable: the arguments are the 1337 labels of northeast and northwest sides of the puzzle boundary; the 1338 output is the list of the fillings of the puzzle with the specified 1339 pieces. 1681 1340 1682 1341 INPUT: 1683 1342 1684  ``puzzle_pieces``  takes either a list of puzzle pieces or a string 1685 "H", "HT", "K", "H2step", "HT2step", "BK" to indicate the Grassmannian, 1686 equivariant Grassmannian, Ktheory, Grassmannian 2 step, equivariant 1687 Grassmannian 2 step or BelkaleKumar puzzle pieces. 1343  ``puzzle_pieces``  takes either a collection of puzzle pieces or 1344 a string indicating a preprogrammed collection of puzzle pieces: 1688 1345 1689  ``maxLetter``  (default: None) None or positive integer which only needs 1690 to be specified for BelkaleKumar puzzle pieces. 1346  ``H``  cohomology of the Grassmannian 1347  ``HT``  equivariant cohomology of the Grassmannian 1348  ``K``  Ktheory 1349  ``H2step``  cohomology of the *2step* Grassmannian 1350  ``HT2step``  equivariant cohomology of the *2step* Grassmannian 1351  ``BK``  BelkaleKumar puzzle pieces 1691 1352 1692 OUTPUT: 1353  ``max_letter``  (default: None) None or a positive integer. This is 1354 only required only for BelkaleKumar puzzles. 1693 1355 1694  function that takes as input the outer label of two sides of the puzzle boundary 1695 and returns the list of puzzle fillings 1356 EXAMPLES: 1696 1357 1697 EXAMPLES:: 1358 Each puzzle piece is an edgelabelled triangle oriented in such a way 1359 that it has a south edge (called a *delta* piece) or a north edge 1360 (called a *nabla* piece). For example, the puzzle pieces corresponding 1361 to the cohomology of the Grassmannian are the following:: 1698 1362 1699 1363 sage: from sage.combinat.knutson_tao_puzzles import H_grassmannian_pieces 1700 sage: ps = PuzzleSolver(H_grassmannian_pieces()) 1364 sage: H_grassmannian_pieces() 1365 Nablas : [0\0/0, 0\10/1, 10\1/0, 1\0/10, 1\1/1] 1366 Deltas : [0/0\0, 0/1\10, 1/10\0, 1/1\1, 10/0\1] 1367 1368 In the string representation, the nabla pieces are depicted as 1369 ``c\a/b``, where `a` is the label of the north edge, `b` is the label 1370 of the southeast edge, `c` is the label of the southwest edge. 1371 A similar string representation exists for the delta pieces. 1372 1373 To create a puzzle solver, one specifies a collection of puzzle pieces:: 1374 1375 sage: KnutsonTaoPuzzleSolver(H_grassmannian_pieces()) 1376 KnutsonTao puzzle solver with pieces: 1377 Nablas : [0\0/0, 0\10/1, 10\1/0, 1\0/10, 1\1/1] 1378 Deltas : [0/0\0, 0/1\10, 1/10\0, 1/1\1, 10/0\1] 1379 1380 The following shorthand to create the above puzzle solver is also supported:: 1381 1382 sage: KnutsonTaoPuzzleSolver('H') 1383 KnutsonTao puzzle solver with pieces: 1384 Nablas : [0\0/0, 0\10/1, 10\1/0, 1\0/10, 1\1/1] 1385 Deltas : [0/0\0, 0/1\10, 1/10\0, 1/1\1, 10/0\1] 1386 1387 The solver will compute all fillings of the puzzle with the given 1388 puzzle pieces. The user specifies the labels of northeast and 1389 northwest sides of the puzzle boundary and the output is a list of the 1390 fillings of the puzzle with the specified pieces. For example, there is 1391 one solution to the puzzle whose northwest and northeast edges are 1392 both labeled '0':: 1393 1394 sage: ps = KnutsonTaoPuzzleSolver('H') 1701 1395 sage: ps('0', '0') 1702 1396 [{(1, 1): 0/0\0}] 1703 1397 1398 There are two solutions to the puzzle whose northwest and northeast 1399 edges are both labeled '0101':: 1400 1401 sage: ps = KnutsonTaoPuzzleSolver('H') 1402 sage: solns = ps('0101', '0101') 1403 sage: len(solns) 1404 2 1405 sage: solns.sort(key=str) 1406 sage: solns 1407 [{(1, 2): 1/\0 0\/1, (1, 3): 0/\0 0\/0, (3, 3): 1/1\1, (4, 4): 10/0\1, (1, 4): 1/\0 0\/1, (1, 1): 0/0\0, (2, 3): 0/\10 1\/1, (2, 2): 1/1\1, (3, 4): 0/\0 1\/10, (2, 4): 1/\1 10\/0}, 1408 {(1, 2): 1/\1 10\/0, (1, 3): 0/\0 1\/10, (3, 3): 0/0\0, (4, 4): 1/1\1, (1, 4): 1/\0 0\/1, (1, 1): 0/1\10, (2, 3): 10/\1 0\/0, (2, 2): 0/0\0, (3, 4): 1/\0 0\/1, (2, 4): 1/\1 1\/1}] 1409 1410 The pieces in a puzzle filling are indexed by pairs of nonnegative 1411 integers `(i, j)` with `1 \leq i \leq j \leq n`, where `n` is the 1412 length of the word labelling the triangle edge. The pieces indexed by 1413 `(i, i)` are the triangles along the south edge of the puzzle. :: 1414 1415 sage: f = solns[0] 1416 sage: [f[i, i] for i in range(1,5)] 1417 [0/0\0, 1/1\1, 1/1\1, 10/0\1] 1418 1419 The pieces indexed by `(i, j)` for `j > i` are a pair consisting of 1420 a delta piece and nabla piece glued together along the south edge and 1421 north edge, respectively (these pairs are called *rhombi*). :: 1422 1423 sage: f = solns[0] 1424 sage: f[1, 2] 1425 1/\0 0\/1 1426 1427 Below are examples of using each of the currently supported puzzles. 1428 1429 Cohomology of the Grassmannian:: 1430 1431 sage: ps = KnutsonTaoPuzzleSolver("H") 1432 sage: solns = ps('0101', '0101') 1433 sage: sorted(solns, key=str) 1434 [{(1, 2): 1/\0 0\/1, (1, 3): 0/\0 0\/0, (3, 3): 1/1\1, (4, 4): 10/0\1, (1, 4): 1/\0 0\/1, (1, 1): 0/0\0, (2, 3): 0/\10 1\/1, (2, 2): 1/1\1, (3, 4): 0/\0 1\/10, (2, 4): 1/\1 10\/0}, 1435 {(1, 2): 1/\1 10\/0, (1, 3): 0/\0 1\/10, (3, 3): 0/0\0, (4, 4): 1/1\1, (1, 4): 1/\0 0\/1, (1, 1): 0/1\10, (2, 3): 10/\1 0\/0, (2, 2): 0/0\0, (3, 4): 1/\0 0\/1, (2, 4): 1/\1 1\/1}] 1436 1437 Equivariant puzzles:: 1438 1439 sage: ps = KnutsonTaoPuzzleSolver("HT") 1440 sage: solns = ps('0101', '0101') 1441 sage: sorted(solns, key=str) 1442 [{(1, 2): 1/\0 0\/1, (1, 3): 0/\0 0\/0, (3, 3): 0/0\0, (4, 4): 1/1\1, (1, 4): 1/\0 0\/1, (1, 1): 0/0\0, (2, 3): 0/\1 1\/0, (2, 2): 1/1\1, (3, 4): 1/\0 0\/1, (2, 4): 1/\1 1\/1}, 1443 {(1, 2): 1/\0 0\/1, (1, 3): 0/\0 0\/0, (3, 3): 1/1\1, (4, 4): 10/0\1, (1, 4): 1/\0 0\/1, (1, 1): 0/0\0, (2, 3): 0/\10 1\/1, (2, 2): 1/1\1, (3, 4): 0/\0 1\/10, (2, 4): 1/\1 10\/0}, 1444 {(1, 2): 1/\1 10\/0, (1, 3): 0/\0 1\/10, (3, 3): 0/0\0, (4, 4): 1/1\1, (1, 4): 1/\0 0\/1, (1, 1): 0/1\10, (2, 3): 10/\1 0\/0, (2, 2): 0/0\0, (3, 4): 1/\0 0\/1, (2, 4): 1/\1 1\/1}] 1445 1446 KTheory puzzles:: 1447 1448 sage: ps = KnutsonTaoPuzzleSolver("K") 1449 sage: solns = ps('0101', '0101') 1450 sage: sorted(solns, key=str) 1451 [{(1, 2): 1/\0 0\/1, (1, 3): 0/\0 0\/0, (3, 3): 1/1\1, (4, 4): 10/0\1, (1, 4): 1/\0 0\/1, (1, 1): 0/0\0, (2, 3): 0/\10 1\/1, (2, 2): 1/1\1, (3, 4): 0/\0 1\/10, (2, 4): 1/\1 10\/0}, 1452 {(1, 2): 1/\1 10\/0, (1, 3): 0/\0 1\/10, (3, 3): 0/0\0, (4, 4): 1/1\1, (1, 4): 1/\0 0\/1, (1, 1): 0/1\10, (2, 3): 10/\1 0\/0, (2, 2): 0/0\0, (3, 4): 1/\0 0\/1, (2, 4): 1/\1 1\/1}, 1453 {(1, 2): 1/\1 10\/0, (1, 3): 0/\0 1\/K, (3, 3): 1/1\1, (4, 4): 10/0\1, (1, 4): 1/\0 0\/1, (1, 1): 0/1\10, (2, 3): K/\K 0\/1, (2, 2): 0/0\0, (3, 4): 0/\0 1\/10, (2, 4): 1/\1 K\/0}] 1454 1455 Twostep puzzles:: 1456 1457 sage: ps = KnutsonTaoPuzzleSolver("H2step") 1458 sage: solns = ps('01201', '01021') 1459 sage: sorted(solns, key=str) 1460 [{(1, 2): 1/\0 0\/1, (1, 3): 2/\0 0\/2, (3, 3): 1/1\1, (4, 5): 20/\2 1\/10, (4, 4): 1/1\1, (5, 5): 10/0\1, (1, 4): 0/\0 0\/0, (1, 1): 0/0\0, (1, 5): 1/\0 0\/1, (2, 3): 2/\2 21\/1, (2, 2): 1/2\21, (2, 5): 1/\1 10\/0, (3, 4): 21/\2 1\/1, (2, 4): 0/\10 2\/21, (3, 5): 0/\0 2\/20}, 1461 {(1, 2): 1/\1 10\/0, (1, 3): 2/\1 1\/2, (3, 3): 0/0\0, (4, 5): 2(10)/\2 0\/1, (4, 4): 0/0\0, (5, 5): 1/1\1, (1, 4): 0/\0 1\/10, (1, 1): 0/1\10, (1, 5): 1/\0 0\/1, (2, 3): 2/\2 20\/0, (2, 2): 0/2\20, (2, 5): 1/\1 1\/1, (3, 4): 20/\2 0\/0, (2, 4): 10/\1 2\/20, (3, 5): 1/\0 2\/2(10)}, 1462 {(1, 2): 1/\21 20\/0, (1, 3): 2/\2 21\/1, (3, 3): 1/1\1, (4, 5): 21/\2 1\/1, (4, 4): 10/0\1, (5, 5): 1/1\1, (1, 4): 0/\0 2\/20, (1, 1): 0/2\20, (1, 5): 1/\0 0\/1, (2, 3): 1/\0 0\/1, (2, 2): 0/0\0, (2, 5): 1/\1 2\/21, (3, 4): 0/\0 1\/10, (2, 4): 20/\2 0\/0, (3, 5): 21/\0 0\/21}] 1463 1464 Twostep equivariant puzzles:: 1465 1466 sage: ps = KnutsonTaoPuzzleSolver("HT2step") 1467 sage: solns = ps('10212', '12012') 1468 sage: sorted(solns, key=str) 1469 [{(1, 2): 0/\(21)0 1\/2, (1, 3): 2/\1 (21)0\/0, (3, 3): 0/0\0, (4, 5): 1/\1 2\/21, (4, 4): 2/2\2, (5, 5): 21/1\2, (1, 4): 1/\1 1\/1, (1, 1): 1/1\1, (1, 5): 2/\1 1\/2, (2, 3): 0/\2 2\/0, (2, 2): 2/2\2, (2, 5): 2/\2 21\/1, (3, 4): 2/\0 0\/2, (2, 4): 1/\21 2\/2, (3, 5): 1/\0 0\/1}, 1470 {(1, 2): 0/\(21)0 1\/2, (1, 3): 2/\1 (21)0\/0, (3, 3): 0/0\0, (4, 5): 2/\1 1\/2, (4, 4): 1/1\1, (5, 5): 2/2\2, (1, 4): 1/\1 1\/1, (1, 1): 1/1\1, (1, 5): 2/\1 1\/2, (2, 3): 0/\2 2\/0, (2, 2): 2/2\2, (2, 5): 2/\2 2\/2, (3, 4): 1/\0 0\/1, (2, 4): 1/\2 2\/1, (3, 5): 2/\0 0\/2}, 1471 {(1, 2): 0/\(21)0 1\/2, (1, 3): 2/\1 (21)0\/0, (3, 3): 2/2\2, (4, 5): 1/\1 2\/21, (4, 4): 20/0\2, (5, 5): 21/1\2, (1, 4): 1/\1 1\/1, (1, 1): 1/1\1, (1, 5): 2/\1 1\/2, (2, 3): 0/\20 2\/2, (2, 2): 2/2\2, (2, 5): 2/\2 21\/1, (3, 4): 0/\0 2\/20, (2, 4): 1/\21 20\/0, (3, 5): 1/\0 0\/1}, 1472 {(1, 2): 0/\1 1\/0, (1, 3): 2/\1 1\/2, (3, 3): 0/0\0, (4, 5): 1/\1 2\/21, (4, 4): 2/2\2, (5, 5): 21/1\2, (1, 4): 1/\1 1\/1, (1, 1): 1/1\1, (1, 5): 2/\1 1\/2, (2, 3): 2/\2 20\/0, (2, 2): 0/2\20, (2, 5): 2/\2 21\/1, (3, 4): 2/\0 0\/2, (2, 4): 1/\21 2\/2, (3, 5): 1/\0 0\/1}, 1473 {(1, 2): 0/\1 1\/0, (1, 3): 2/\1 1\/2, (3, 3): 0/0\0, (4, 5): 2/\1 1\/2, (4, 4): 1/1\1, (5, 5): 2/2\2, (1, 4): 1/\1 1\/1, (1, 1): 1/1\1, (1, 5): 2/\1 1\/2, (2, 3): 2/\2 20\/0, (2, 2): 0/2\20, (2, 5): 2/\2 2\/2, (3, 4): 1/\0 0\/1, (2, 4): 1/\2 2\/1, (3, 5): 2/\0 0\/2}, 1474 {(1, 2): 0/\10 1\/1, (1, 3): 2/\10 10\/2, (3, 3): 1/1\1, (4, 5): 10/\1 2\/20, (4, 4): 2/2\2, (5, 5): 20/0\2, (1, 4): 1/\1 10\/0, (1, 1): 1/1\1, (1, 5): 2/\1 1\/2, (2, 3): 2/\2 21\/1, (2, 2): 1/2\21, (2, 5): 2/\2 20\/0, (3, 4): 2/\1 1\/2, (2, 4): 0/\20 2\/2, (3, 5): 0/\0 1\/10}, 1475 {(1, 2): 0/\10 1\/1, (1, 3): 2/\10 10\/2, (3, 3): 1/1\1, (4, 5): 2/\1 1\/2, (4, 4): 10/0\1, (5, 5): 2/2\2, (1, 4): 1/\1 10\/0, (1, 1): 1/1\1, (1, 5): 2/\1 1\/2, (2, 3): 2/\2 21\/1, (2, 2): 1/2\21, (2, 5): 2/\2 2\/2, (3, 4): 0/\0 1\/10, (2, 4): 0/\2 2\/0, (3, 5): 2/\0 0\/2}, 1476 {(1, 2): 0/\20 21\/1, (1, 3): 2/\2 20\/0, (3, 3): 0/0\0, (4, 5): 2/\1 1\/2, (4, 4): 1/1\1, (5, 5): 2/2\2, (1, 4): 1/\1 2\/21, (1, 1): 1/2\21, (1, 5): 2/\1 1\/2, (2, 3): 0/\1 1\/0, (2, 2): 1/1\1, (2, 5): 2/\2 2\/2, (3, 4): 1/\0 0\/1, (2, 4): 21/\2 1\/1, (3, 5): 2/\0 0\/2}, 1477 {(1, 2): 0/\20 21\/1, (1, 3): 2/\2 20\/0, (3, 3): 1/1\1, (4, 5): 2/\1 1\/2, (4, 4): 10/0\1, (5, 5): 2/2\2, (1, 4): 1/\1 2\/21, (1, 1): 1/2\21, (1, 5): 2/\1 1\/2, (2, 3): 0/\10 1\/1, (2, 2): 1/1\1, (2, 5): 2/\2 2\/2, (3, 4): 0/\0 1\/10, (2, 4): 21/\2 10\/0, (3, 5): 2/\0 0\/2}, 1478 {(1, 2): 0/\21 21\/0, (1, 3): 2/\2 21\/1, (3, 3): 0/0\0, (4, 5): 2/\1 1\/2, (4, 4): 1/1\1, (5, 5): 2/2\2, (1, 4): 1/\1 2\/21, (1, 1): 1/2\21, (1, 5): 2/\1 1\/2, (2, 3): 1/\1 10\/0, (2, 2): 0/1\10, (2, 5): 2/\2 2\/2, (3, 4): 1/\0 0\/1, (2, 4): 21/\2 1\/1, (3, 5): 2/\0 0\/2}] 1479 1480 1481 BelkaleKumar puzzles:: 1482 1483 sage: ps = KnutsonTaoPuzzleSolver("BK", 3) 1484 sage: solns = ps('10212', '12012') 1485 sage: sorted(solns, key=str) 1486 1704 1487 TESTS: 1705 1488 1706 1489 Check that UniqueRepresentation works:: 1707 1490 1708 sage: from sage.combinat.knutson_tao_puzzles import H_grassmannian_pieces1709 sage: ps = PuzzleSolver(H_grassmannian_pieces())1710 sage: qs = PuzzleSolver("H")1491 sage: from sage.combinat.knutson_tao_puzzles import KnutsonTaoPuzzleSolver, H_grassmannian_pieces 1492 sage: ps = KnutsonTaoPuzzleSolver(H_grassmannian_pieces()) 1493 sage: qs = KnutsonTaoPuzzleSolver("H") 1711 1494 sage: ps 1712 1495 KnutsonTao puzzle solver with pieces: 1713 1496 Nablas : [0\0/0, 0\10/1, 10\1/0, 1\0/10, 1\1/1] … … class PuzzleSolver(UniqueRepresentation) 1724 1507 self._bottom_deltas = tuple(puzzle_pieces.boundary_deltas()) 1725 1508 1726 1509 @staticmethod 1727 def __classcall_private__(cls, puzzle_pieces, max Letter=None):1510 def __classcall_private__(cls, puzzle_pieces, max_letter=None): 1728 1511 """ 1729 1512 TESTS:: 1730 1513 1731 1514 sage: from sage.combinat.knutson_tao_puzzles import * 1732 sage: PuzzleSolver(H_grassmannian_pieces()) ==PuzzleSolver("H") # indirect doctest1515 sage: KnutsonTaoPuzzleSolver(H_grassmannian_pieces()) == KnutsonTaoPuzzleSolver("H") # indirect doctest 1733 1516 True 1734 sage: PuzzleSolver(HT_grassmannian_pieces()) ==PuzzleSolver("HT")1517 sage: KnutsonTaoPuzzleSolver(HT_grassmannian_pieces()) == KnutsonTaoPuzzleSolver("HT") 1735 1518 True 1736 sage: PuzzleSolver(K_grassmannian_pieces()) ==PuzzleSolver("K")1519 sage: KnutsonTaoPuzzleSolver(K_grassmannian_pieces()) == KnutsonTaoPuzzleSolver("K") 1737 1520 True 1738 sage: PuzzleSolver(H_two_step_pieces()) ==PuzzleSolver("H2step")1521 sage: KnutsonTaoPuzzleSolver(H_two_step_pieces()) == KnutsonTaoPuzzleSolver("H2step") 1739 1522 True 1740 sage: PuzzleSolver(HT_two_step_pieces()) ==PuzzleSolver("HT2step")1523 sage: KnutsonTaoPuzzleSolver(HT_two_step_pieces()) == KnutsonTaoPuzzleSolver("HT2step") 1741 1524 True 1742 sage: PuzzleSolver(BK_pieces(3)) ==PuzzleSolver("BK",3)1525 sage: KnutsonTaoPuzzleSolver(BK_pieces(3)) == KnutsonTaoPuzzleSolver("BK",3) 1743 1526 True 1744 1527 """ 1745 1528 if isinstance(puzzle_pieces, str): … … class PuzzleSolver(UniqueRepresentation) 1754 1537 elif puzzle_pieces == "HT2step": 1755 1538 puzzle_pieces = HT_two_step_pieces() 1756 1539 elif puzzle_pieces == "BK": 1757 if max Letter is not None:1758 puzzle_pieces = BK_pieces(max Letter)1540 if max_letter is not None: 1541 puzzle_pieces = BK_pieces(max_letter) 1759 1542 else: 1760 raise ValueError, "max Letter needs to be specified"1761 return super( PuzzleSolver, cls).__classcall__(cls, puzzle_pieces)1543 raise ValueError, "max_letter needs to be specified" 1544 return super(KnutsonTaoPuzzleSolver, cls).__classcall__(cls, puzzle_pieces) 1762 1545 1763 1546 def __call__(self, lamda, mu, algorithm='strips'): 1764 1547 """ 1765 1548 TESTS:: 1766 1549 1767 sage: ps = PuzzleSolver("H") 1550 sage: from sage.combinat.knutson_tao_puzzles import KnutsonTaoPuzzleSolver 1551 sage: ps = KnutsonTaoPuzzleSolver("H") 1768 1552 sage: ps('0101','1001') 1769 1553 [{(1, 2): 1/\1 10\/0, (1, 3): 0/\10 1\/1, (3, 3): 1/1\1, (4, 4): 10/0\1, (1, 4): 1/\1 10\/0, 1770 1554 (1, 1): 0/1\10, (2, 3): 1/\0 0\/1, (2, 2): 0/0\0, (3, 4): 0/\0 1\/10, (2, 4): 0/\0 0\/0}] … … class PuzzleSolver(UniqueRepresentation) 1784 1568 """ 1785 1569 EXAMPLES:: 1786 1570 1787 sage: from sage.combinat.knutson_tao_puzzles import H_grassmannian_pieces1788 sage: PuzzleSolver(H_grassmannian_pieces())1571 sage: from sage.combinat.knutson_tao_puzzles import KnutsonTaoPuzzleSolver 1572 sage: KnutsonTaoPuzzleSolver('H') 1789 1573 KnutsonTao puzzle solver with pieces: 1790 1574 Nablas : [0\0/0, 0\10/1, 10\1/0, 1\0/10, 1\1/1] 1791 1575 Deltas : [0/0\0, 0/1\10, 1/10\0, 1/1\1, 10/0\1] … … class PuzzleSolver(UniqueRepresentation) 1807 1591 1808 1592 EXAMPLES:: 1809 1593 1810 sage: from sage.combinat.knutson_tao_puzzles import H_grassmannian_pieces1811 sage: ps = PuzzleSolver(H_grassmannian_pieces())1594 sage: from sage.combinat.knutson_tao_puzzles import KnutsonTaoPuzzleSolver 1595 sage: ps = KnutsonTaoPuzzleSolver('H') 1812 1596 sage: ps._fill_piece('0', '0', ps._bottom_deltas) 1813 1597 [0/0\0] 1814 1598 """ … … class PuzzleSolver(UniqueRepresentation) 1837 1621 1838 1622 EXAMPLES:: 1839 1623 1840 sage: from sage.combinat.knutson_tao_puzzles import H_grassmannian_pieces1841 sage: ps = PuzzleSolver(H_grassmannian_pieces())1624 sage: from sage.combinat.knutson_tao_puzzles import KnutsonTaoPuzzleSolver 1625 sage: ps = KnutsonTaoPuzzleSolver('H') 1842 1626 sage: ps._fill_strip(('0',), '0', ps._rhombus_pieces, ps._bottom_deltas) 1843 1627 [[0/0\0]] 1844 1628 sage: ps._fill_strip(('0','0'), '0', ps._rhombus_pieces, ps._bottom_deltas) … … class PuzzleSolver(UniqueRepresentation) 1850 1634 1851 1635 TESTS:: 1852 1636 1853 sage: from sage.combinat.knutson_tao_puzzles import H_grassmannian_pieces1854 sage: ps = PuzzleSolver(H_grassmannian_pieces())1637 sage: from sage.combinat.knutson_tao_puzzles import KnutsonTaoPuzzleSolver 1638 sage: ps = KnutsonTaoPuzzleSolver('H') 1855 1639 sage: ps._fill_strip(('0',), 'goo', ps._rhombus_pieces) 1856 1640 [] 1857 1641 """ … … class PuzzleSolver(UniqueRepresentation) 1877 1661 1878 1662 EXAMPLES:: 1879 1663 1880 sage: from sage.combinat.knutson_tao_puzzles import H_grassmannian_pieces1881 sage: ps = PuzzleSolver(H_grassmannian_pieces())1664 sage: from sage.combinat.knutson_tao_puzzles import KnutsonTaoPuzzleSolver 1665 sage: ps = KnutsonTaoPuzzleSolver('H') 1882 1666 sage: list(ps._fill_puzzle_by_pieces('0', '0')) 1883 1667 [{(1, 1): 0/0\0}] 1884 1668 """ 1885 queue = [P artialPuzzle(lamda, mu)]1669 queue = [PuzzleFilling(lamda, mu)] 1886 1670 while queue: 1887 1671 PP = queue.pop() 1888 1672 ne_label = PP.north_east_label_of_kink() … … class PuzzleSolver(UniqueRepresentation) 1905 1689 1906 1690 EXAMPLES:: 1907 1691 1908 sage: from sage.combinat.knutson_tao_puzzles import H_grassmannian_pieces1909 sage: ps = PuzzleSolver(H_grassmannian_pieces())1692 sage: from sage.combinat.knutson_tao_puzzles import KnutsonTaoPuzzleSolver 1693 sage: ps = KnutsonTaoPuzzleSolver('H') 1910 1694 sage: list(ps._fill_puzzle_by_strips('0', '0')) 1911 1695 [{(1, 1): 0/0\0}] 1912 1696 sage: list(ps._fill_puzzle_by_strips('01', '01')) 1913 1697 [{(1, 2): 1/\0 0\/1, (1, 1): 0/0\0, (2, 2): 1/1\1}] 1914 1698 """ 1915 queue = [P artialPuzzle(lamda, mu)]1699 queue = [PuzzleFilling(lamda, mu)] 1916 1700 while queue: 1917 1701 PP = queue.pop() 1918 1702 (i, j) = PP.kink_coordinates() … … class PuzzleSolver(UniqueRepresentation) 1947 1731 1948 1732 EXAMPLES:: 1949 1733 1950 sage: from sage.combinat.knutson_tao_puzzles import K _grassmannian_pieces1951 sage: ps = PuzzleSolver(K_grassmannian_pieces())1734 sage: from sage.combinat.knutson_tao_puzzles import KnutsonTaoPuzzleSolver 1735 sage: ps = KnutsonTaoPuzzleSolver('K') 1952 1736 sage: solns = ps('0101', '0101') 1953 1737 sage: ps.plot(solns) # not tested 1954 1738 """ … … class PuzzleSolver(UniqueRepresentation) 1957 1741 m = len([gg.axes(False) for gg in g]) 1958 1742 return graphics_array(g, (m+3)/4, 4) 1959 1743 1744 def structure_constants(self, lamda, mu, nu=None): 1745 r""" 1746 Compute cohomology structure coefficients from puzzles. 1960 1747 1961 class SchubertCalculusAlgebra(CombinatorialFreeModule):1962 """1963 Schubert calculus algebra computed from puzzles.1964 1965 The Schubert calculus algebra can be used to compute products in the Schubert algebra.1966 It can be computed in the various settings that the puzzles exist for.1967 1968 INPUT:1969 1970  ``R``  ground ring1971  ``content``  tuple: the `i`th entry in ``content`` specifies the number of `i`th in the words that label the basis1972  ``equivariance``, ``K``, ``BK``  boolean1973 1974 EXAMPLES::1975 1976 sage: from sage.combinat.knutson_tao_puzzles import SchubertCalculusAlgebra1977 sage: Sc = SchubertCalculusAlgebra(QQ, (2,1), equivariance = True).basis()1978 sage: Sc[Word('100')]1979 Sc[100]1980 sage: Sc[Word('100')]*Sc[Word('100')]1981 (y1^2y1*y2y1*y3+y2*y3)*Sc[100]1982 1983 sage: Sc = SchubertCalculusAlgebra(QQ, (2,2)).basis()1984 sage: Sc.an_element()1985 Sc[0011]1986 sage: Sc.an_element()*Sc.an_element()1987 Sc[0011]1988 1989 sage: Sc = SchubertCalculusAlgebra(QQ, (2,2), K=True).basis()1990 sage: Sc[Word('1010')]*Sc[Word('0101')]1991 Sc[1100]1992 """1993 1994 def __init__(self, R, content, equivariance=False, K=False, BK=False):1995 """1996 1748 INPUT: 1997 1749 1998  ``R``  ground ring 1999  ``content``  tuple: the `i`th entry in ``content`` specifies the number of `i`th 2000  ``equivariance``, ``K``, ``BK``  boolean 1750  ``pieces``  puzzle pieces to be used 1751  ``lambda``, ``mu``  edge labels of puzzle for northwest and north east side 1752  ``nu``  (default: ``None``) If ``nu`` is not specified a dictionary is returned with 1753 the structure coefficients corresponding to all south labels; if ``nu`` is given, only 1754 the coefficients with the specified label is returned. 2001 1755 2002 EXAMPLES::1756 OUTPUT: dictionary 2003 1757 2004 sage: from sage.combinat.knutson_tao_puzzles import SchubertCalculusAlgebra 2005 sage: SchubertCalculusAlgebra(QQ, (3,2)) # indirect doctest 2006 Schubert Calculus Algebra over the Rational Field 2007 """ 2008 from sage.misc.flatten import flatten 2009 basis_elements = [Word()] 2010 for i in range(len(content)): 2011 w = [str(i)]*content[i] 2012 basis_elements = flatten([b.shuffle(w).list() for b in basis_elements]) 1758 EXAMPLES: 2013 1759 2014 CombinatorialFreeModule.__init__(self, R, basis_elements,2015 prefix='Sc',2016 category = AlgebrasWithBasis(R))1760 Note: In order to standardize the output of the following examples, 1761 we output a sorted list of items from the dictionary instead of the 1762 dictionary itself. 2017 1763 2018 if len(content) == 2: 2019 if equivariance: 2020 self._pieces = HT_grassmannian_pieces() 2021 else: 2022 self._pieces = H_grassmannian_pieces() 2023 elif len(content) == 3: 2024 if equivariance: 2025 self._pieces = HT_two_step_pieces() 2026 else: 2027 self._pieces = H_two_step_pieces() 1764 Grassmannian cohomology:: 2028 1765 2029 if K: 2030 if equivariance or len(content) >= 3: 2031 raise NotImplementedError 2032 else: 2033 self._pieces = K_grassmannian_pieces() 1766 sage: ps = KnutsonTaoPuzzleSolver('H') 1767 sage: cp = ps.structure_constants('0101', '0101') 1768 sage: sorted(cp.items(), key=str) 1769 [(('0', '1', '1', '0'), 1), (('1', '0', '0', '1'), 1)] 1770 sage: ps.structure_constants('001001', '001010', '010100') 1771 1 2034 1772 2035 #if BK: 2036 # if equivariance or K: 2037 # raise NotImplementedError 2038 #else: 2039 # if len(content) > 4: 2040 # raise NotImplementedError 1773 Equivariant cohomology:: 2041 1774 2042 self._puzzle_solver = PuzzleSolver(self._pieces) 1775 sage: ps = KnutsonTaoPuzzleSolver('HT') 1776 sage: cp = ps.structure_constants('0101', '0101') 1777 sage: sorted(cp.items(), key=str) 1778 [(('0', '1', '0', '1'), y2  y3), 1779 (('0', '1', '1', '0'), 1), 1780 (('1', '0', '0', '1'), 1)] 2043 1781 2044 def _repr_(self): 2045 """ 2046 TESTS:: 1782 Ktheory:: 2047 1783 2048 sage: from sage.combinat.knutson_tao_puzzles import SchubertCalculusAlgebra 2049 sage: SchubertCalculusAlgebra(QQ, (3,3)) 2050 Schubert Calculus Algebra over the Rational Field 2051 """ 2052 return "Schubert Calculus Algebra over the %s" % self.base_ring() 1784 sage: ps = KnutsonTaoPuzzleSolver('K') 1785 sage: cp = ps.structure_constants('0101', '0101') 1786 sage: sorted(cp.items(), key=str) 1787 [(('0', '1', '1', '0'), 1), (('1', '0', '0', '1'), 1), (('1', '0', '1', '0'), 1)] 2053 1788 2054 def product_on_basis(self, w, u): 2055 r""" 2056 Computes product between ``w`` and ``u`` in the algebra. 1789 Twostep:: 2057 1790 2058 EXAMPLES:: 1791 sage: ps = KnutsonTaoPuzzleSolver('H2step') 1792 sage: cp = ps.structure_constants('01122', '01122') 1793 sage: sorted(cp.items(), key=str) 1794 [(('0', '1', '1', '2', '2'), 1)] 1795 sage: cp = ps.structure_constants('01201', '01021') 1796 sage: sorted(cp.items(), key=str) 1797 [(('0', '2', '1', '1', '0'), 1), 1798 (('1', '2', '0', '0', '1'), 1), 1799 (('2', '0', '1', '0', '1'), 1)] 2059 1800 2060 sage: from sage.combinat.knutson_tao_puzzles import SchubertCalculusAlgebra 2061 sage: WordOptions(identifier='') 2062 sage: Sc = SchubertCalculusAlgebra(QQ, (3,3)).basis() 2063 sage: Sc[Word('001011')] * Sc[Word('010101')] # indirect doctest 2064 Sc[010110] + Sc[011001] + Sc[100101] 1801 Twostep equivariant:: 1802 1803 sage: ps = KnutsonTaoPuzzleSolver('HT2step') 1804 sage: cp = ps.structure_constants('10212', '12012') 1805 sage: sorted(cp.items(), key=str) 1806 [(('1', '2', '0', '1', '2'), y1*y2  y2*y3  y1*y4 + y3*y4), 1807 (('1', '2', '0', '2', '1'), y1  y3), 1808 (('1', '2', '1', '0', '2'), y2  y4), 1809 (('1', '2', '1', '2', '0'), 1), 1810 (('1', '2', '2', '0', '1'), 1), 1811 (('2', '1', '0', '1', '2'), y1  y3), 1812 (('2', '1', '1', '0', '2'), 1)] 2065 1813 """ 2066 1814 from collections import defaultdict 2067 z = defaultdict(int) 2068 for p in self._puzzle_solver(w, u): 1815 R = PolynomialRing(Integers(), 'y', len(lamda)+1) 1816 z = defaultdict(R.zero) 1817 for p in self(lamda, mu): 2069 1818 z[p.south_labels()] += p.contribution() 2070 return self.sum_of_terms((Word(m), c) for (m, c) in z.iteritems()) 1819 if nu is None: 1820 return dict(z) 1821 else: 1822 return z[tuple(nu)]