File: service-functions.m2

package info (click to toggle)
macaulay2 1.21%2Bds-3
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 133,096 kB
  • sloc: cpp: 110,377; ansic: 16,306; javascript: 4,193; makefile: 3,821; sh: 3,580; lisp: 764; yacc: 590; xml: 177; python: 140; perl: 114; lex: 65; awk: 3
file content (729 lines) | stat: -rw-r--r-- 25,902 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
export {
    "checkIncidenceSolution", 
    "solutionsToAffineCoords", 
    "partition2bracket",
    "bracket2partition",
    "randomSchubertProblemInstance",
    "NSC2phc", 
    "LRnumber"              
    }
----------------
--Functions contained here but not exported:
----------------
-- verifyLength(List, ZZ)
-- partition2bracket(List,ZZ,ZZ)
-- output2partition(List) --input redcheckers
-- output2bracket(List)
-- bracket2partition(List,ZZ)
-- printTree(MutableHashTable)--input node
-- checkNewtonIteration -- this is for testing only should be removed from the final version (test if it works with the new way to create eqns)
-- moveFlags2Flags (List, List) --input two list of flags (F's, G's)
-- MovingFlag'at'Root ZZ
-- notAboveLambda(List,ZZ,ZZ) -- input(lambda, k,n)
-- checkSchubertProblem(List,ZZ,ZZ) - (conds,k,n)  checks that conds forms a Schubert problem
-- verifyInput(List,ZZ,ZZ)


----------------------
--    LRnumber     ---
--
-- Computes the number of solutions to a Schubert 
--   problem on a Grassmannian
----------------------
-- Input: 
--    conds - list of partitions or brackets
--    k,n   - integers that indicate the Grassmannian G(k,n)
-- Output:
--    number of solutions to given Schubert problem
--------------------------------------------------------------------
-- Strategy for computing this intersection number
--   Schubert2  uses the SchubertRing command in the Schubert2 intersection theory package
--   phc        uses PHCPack's implementation of the geometric Littlewood-Richardson rule
--------------------------------------------------------------------
LRnumber = method(Options=>{Strategy=>"Schubert2"})
LRnumber (List,ZZ,ZZ) := o -> (conds,k,n) -> (
    -- First check if it is a Schubert problem
    checkSchubertProblem(conds,k,n);
    if o.Strategy === "phc" then (
	-- obfuscatory snippet of code to call LRrule and parse the output (a string) into a number
	A := (separate("\\[",(separate("\\+", LRrule(n,NSC2phc(conds,k,n)) ))#1))#0 ;
	dgt := reverse( apply(ascii(A), i-> i-48 ) );
	X:={};
	for i from 0 to #dgt-1 do (X = append(X,10^i*dgt#i) );
	sum(X) 
	) 
    else if o.Strategy === "Schubert2" then (
	-- sets up the cohomology ring of the Grassmannian
	G := flagBundle({k,n-k});
	(S,T,U) := schubertRing G;
	a := 1;
	-- detects if brackets or partitions
	if (#conds#0 == k) and (conds#0 == sort unique conds#0) then
	apply( conds, b -> a = a * (schubertCycle(bracket2partition(b,n),G)) ) else 
	apply( conds, p -> a = a * (schubertCycle(verifyLength(p,k),G)) );
	integral a
	)
    else error "unknown Strategy"
)

-----------------------------------------------------------------------------------------
-- ensurePartitions  
--
-- checks that the input (Instance, k, n) is correct; it forms an instance of 
--  a Schubert problem on a Grassmannian, and then returns the Schubert problem, replacing
--  partitions by brackets, if necessary.
-----------------------------------------------------
-- Kludge alert:  if the tolerance for a determinant to be zero, ERROR'TOLERANCE, has not been set, it sets
--   it to 0.001
-----------------------------------------------------------------------------------------
-- Input:
-- Instance  - a list of pairs (c,F), where c is a Schubert condition (partition or bracket) and F a flag
-- k, n      - integers that indicate the Grassmannian G(k,n)
-----------------------------------------------------------------------------------------
-- The purpose of this routine is both to check that the input to solveSchubertProblem and solveSimpleSchubert 
--  does indeed consist of an instance of a Schubert problem, and to allow the conditions to be 
--  brackets as well as partitions.
-----------------------------------------------------------------------------------------

ensurePartitions= method()
ensurePartitions(List,ZZ,ZZ) :=  (conds'flags, k,n) ->(
    conds := conds'flags/first; -- list of Schubert conditions
    flags := conds'flags/last; -- list of flags
    --- check if these conditions impose a 0-dimensional Schubert Problem
    checkSchubertProblem(conds,k,n);
    --- Verify that the flags are square matrices of full rank
    if instance(ERROR'TOLERANCE ,Symbol) then (ERROR'TOLERANCE=0.001);
    scan(flags, F->(
	    if not instance(F,Matrix) or numColumns F != numRows F or abs(det F) < ERROR'TOLERANCE  then error(toString F|" should be an invertible square matrix of size "| toString n)	    
	    ));
    --- Finally, it checks if the conditions are brackets and transforms them into partitions before exporting the instance
    if (#conds_0  == k and conds_0 == sort unique conds_0) then (  --- conds_0, hence conds are brackets
    	   conds = conds/(i-> bracket2partition(i,n));              -- Transform them into partitions
	);
    apply(#conds, i-> (conds_i, flags_i))
    )
------------------------------------------------------------------------------------

------------------------------------------
--  NSC2phc
-- converts from numerical Schubert Calculus data for a Schubert problem
--  (partitions or brackets) to input for PHCPack's data (matrix of multiplicities and brackets)
------------------------------------------
-- Input: 
--    conds - list of partitions or brackets 
--    k,n   - integers that indicate the Grassmannian G(k,n)
-- Output:
--    matrix with ewach row an integer vector with first entry a multiplicity
--     and remaining entries constituting a bracket
------------------------------------------
-- First checks if it is a Schubert problem, then
--  converts to brackets (if needed) and then
--  to the phc input matrix format
------------------------------------------

------------------------------------------
NSC2phc = method ()
NSC2phc (List,ZZ,ZZ) := (conds,k,n) -> (
    -- First check if it is a Schubert problem
    checkSchubertProblem(conds,k,n);
    -- if partitions, convert to a list of brackets 
    if (#conds#0 != k) or (conds#0 != sort unique conds#0) then
       conds = apply(conds, p -> partition2bracket(p,k,n));

    -- convert list of brackets to matrix with each row {m, b}, where
    --  m is the multiplicity of the bracket b (which is opened in this row)
    mults := new MutableHashTable;
    scan((unique conds), b -> mults#b = 0 );
    scan(conds, b -> mults#b=mults#b+1);
    matrix(apply((unique conds), b -> prepend( mults#b,b) ))
)
--------------------------



---------------------
--   verifyLength  --
--
-- makes sure a partition l of k parts
-- has length k and add zeroes at the
-- end if not
--
verifyLength = method(TypicalValue => List)
verifyLength(VisibleList, ZZ) := (l,k) ->(
     x:=new List;
     if #l <= k then (
	  x = for i to k-#l-1 list 0;
	  l | x
     ) else print("partition has too many parts")
)
--------------------------
-- Dictionaries of different notations
--------------------------

--
--  This converts a partition to a bracket
--
partition2bracket = method(TypicalValue => List)
partition2bracket(List,ZZ,ZZ) := (l, k, n) -> (
     l = verifyLength(l, k);
     brackt := for i to #l-1 list (n-k)+(i+1)-l#i
)

--
--  Frank asks: What does this do?
--
output2partition = method(TypicalValue => List)
output2partition(List) := redpos ->(
		n:= #redpos;
		posn := select( redpos, x->x!= NC);
		k:= #posn;
		partitn := new MutableList from k:0;
		apply(#posn, j->(
			partitn#j = n-k+j-posn#j;
		));
		reverse sort toList partitn
)

-- *** not using this function (we use redChkrPos instead)
bracket2input = method(TypicalValue => List)
bracket2input(List,ZZ) := (br,n) ->(
     inp := for i to n-1 list NC;
     inp = new MutableList from inp;
     apply(br, b-> inp#(b-1) = b-1);
     toList inp
)

-- not using this function in general, but when debugging,
-- we might use this function with the columnReduce sometimes
--
-- input: redcheckers
-- output: the bracket condition (read from redCheckers)
--     	   that affects the ID flag
output2bracket = method(TypicalValue=>List)
output2bracket List := outp -> (
     br := select(outp, x-> x!=NC);
     apply(br, x-> x=x+1)
) 

--
--  Converts a bracket into a partition.  This is useful.
--
bracket2partition = method(TypicalValue => List)
bracket2partition(List,ZZ) := (l, n) -> (
--     l = reverse sort l;
     partitn := for i to #l-1 list (n-#l)+(i+1)-l#i 
)

---------

-------------------------
-- printTree (useful when debugging)
-------------------------
-- print Tree is a recursive call of peek 
-- to print all the children of a node
printTree = method()
printTree MutableHashTable := node ->(
	print peek node;
	scan(node.Children, c-> printTree c);
)


----------------------
-- checkNewtonIteration
----------------------
-- Function that given a proposed
-- solution to a Schubert Problem 
-- it creates a Newton step to compare
-- the convergence of the approximated solution
----------------------
-- Input: 
--    Solns - list of solutions (in local coordinates?)
--    Pblm - list of (li,Fi) representing the SchubertProblem
--    (k,n) - sequence with (k,n) that indicate the Grassmannian G(k,n)
-- Output:
--    Newt - List where each entry is the l_1 norm of (s-NewtStep(s)) for s\in Solns
--------------------------------------------------------------------
--       ?? This is the info necessary to create a system of eqns
--------------------------------------------------------------------
--    *** NOT USING THIS FUNCTION ***
--
--   Frank thinks that this might be a useful alternative to checkIncidenceSolution.
--    However, he has yet to find an instance where checkIncidenceSolution fails (but it should sometime)
--
checkNewtonIteration = method()
checkNewtonIteration (List,List,Sequence) := (Solns, Pblm, kn)->(
    (k,n):= kn;
    -- we create a random change of coordinates:
    A:= random(FFF^n,FFF^n);
    SolTransformed := Solns/(i->A*i);
    PblmTransf := apply(Pblm, CF->(
	    (c,f):=CF;
	    (c,A*f)
	    ));
    -- we choose coordinates for the Grassmannian
    X := symbol X;
    RX:=FFF[X_{0,0}..X_{(n-k)-1,k-1}];
    Vs := first entries vars RX;
    coordX := matrix pack(first entries vars RX,k)||id_(FFF^k);
    polySyst := makePolynomials(coordX,PblmTransf);
    solsInCoordsX := solutionsToAffineCoords SolTransformed;
    solutions := apply(solsInCoordsX, X-> toRawSolutions(coordX,X));
    squareSyst:=first entries squareUpPolynomials(numgens ring polySyst, polySyst);
    -- we compute the Jacobian of the system
    JacSystem := for i in squareSyst list for j in Vs list diff(j,i);
    ID:=id_(FFF^(#Vs));
    apply(solutions, newt->(
	    Mp := (map(FFF,RX,matrix{newt}));
    	    JacEval := Mp matrix JacSystem;
	    Jinv := solve(JacEval, ID);
	    Jinv*transpose(Mp matrix{squareSyst})
	    ))
    )


------------------------
-- solutionsToAffineCoords
------------------------
-- writing the solutions in global coords
-- as a set of solutions in terms of my
-- favorite coordinate chart:
-- s = [**||id] the identity on bottom
-------------------------
-- Caveat!!!
-------------------------
-- THIS MAY FAIL if the solutions are
-- not in general position (if they cannot fit this local coords)
-- i.e. when T cannot be computed
--
-- One way to avoid this is taking a random linear 
-- transformation of the solutions (and flags) before calling
-- this function
--------------------------------------------------
-- *** ONLY used in checkNewtonIteration which is no longer used
--------------------------------------------------
solutionsToAffineCoords = method()
solutionsToAffineCoords List := Solutions ->(
    apply(Solutions, s->(
	    k:=numColumns(s);
	    n:=numRows(s);
    	    b:= id_(FFF^k);
    	    T:= solve(submatrix(s,n-k..n-1,0..k-1),b);
	    clean(0.001,s*T)
	    ))
    )


----------------------
-- checkIncidenceSolution
----------------------
-- August 20,2013
-- THIS FUNCTION NEEDS TO BE DELETED??  (Does it?)
-- it was for testing solutions of Schubert varieties
-- but this is not numerical stable... we replace this
-- with a Newton step check
----------------------
-- Function that given a proposed 
-- n by k matrix, and a list of Schubert conditions and flags,
--  it checks if the matrix satisfies the incidence conditions
--  by computing the corresponding minors and see if they vanish
----------------------
-- Input:
--    H -- n by k matrix (representing an element of G(k,n)
--        (make it so that H can have matrices with variables)
--    SchbPrblm -- Schubert problem given as
--    	           list of sequences of the form
--    	      	   {(l1,F1),...,(lm,Fm)}
-- Output:
--    True or False
-----------------------
checkIncidenceSolution = method()
checkIncidenceSolution(Matrix, List) := (H, SchbPrblm) ->(
  n:= numRows H;
  k:= numColumns H;
  verif:= true;
  scan(SchbPrblm, T->(
    (l,F) := T; -- (partition, flag)
    b:=partition2bracket(l,k,n);
    HXF:=promote(H|F,ring H);
    scan(#b, r->( 
       c := b#r;
       rnk := k+c-(r+1)+1;
       if(rnk<= n) then(
         chooseCols:= subsets(k+c,rnk);
	 chooseRows:= subsets(n,rnk);
	 scan(chooseRows, rws->(
	   scan(chooseCols, cls->(
		   n := norm det submatrix(HXF_{0..k+c-1},rws,cls);
		   if n>ERROR'TOLERANCE then(
	               verif=false;
		       print("These are the NONZERO residuals");
 		       print(n);
	               );
	      	   ));
             ));
         );
      ));
    ));
  verif
  )

--
-- TEST
-- H = promote(matrix{{1,0},{0,0},{0,1},{0,0}},FFF)
-- SchbPrblm = {({2,1},id_(FFF^4)),({1,0}, rsort id_(FFF^4))}
-- checkIncidenceSolution(H, SchbPrblm)
-- 
-- SchbPrblm = {({2,1},id_(FFF^4)),({1,0}, random(FFF^4,FFF^4))}
-- checkIncidenceSolution(H, SchbPrblm)


-------------------------------
-- moveFlags2Flags
--
-- function that finds linear transformations
-- to send two flags (F1, F2) to other two
-- flags (G1,G2). The idea is based on the fact
-- that any two flags can be send to the standard
-- flag and the opposite standard flag.
--
-- The idea is to get a matrix A in GL(n)
-- and two triangular matrices T1, T2 such that
--
--   A*F1*T1^-1 = G1
--   A*F2*T2^-1 = G2
---------------------------------
-- Input:
--    {F1,F2} - list of two start flags
--    {G1,G2} - list of two target flags
-- Output:
--    (A,T1,T2) - sequence of three matrices
--         A - invertible nxn matrix
--         T1 - upper triangular matrix
--              with 1's in the diagonal
--         T2 - upper triangular matrix with nonzero
--              entries in the diagonal
---------------------------------
moveFlags2Flags = method()
moveFlags2Flags (List, List) := (F's, G's)->(
    F1:=first F's;
    F2:=last F's;
    G1:=first G's;
    G2:=last G's;
    n:=numColumns F1;
    a := symbol a;
    x := symbol x;
    y := symbol y;
    indx:= subsets(0..n-1,2)/toSequence;
    Vars := sort(flatten apply(indx, i-> {x_(i),y_(i)})|apply(n,i-> y_(i,i)));
    R:= (ring F1)[a_(0,0)..a_(n-1,n-1),Vars];
    A := genericMatrix(R,n,n);
    T1 := mutableIdentity(R,n);
    T2 := mutableIdentity(R,n);
    scan(indx, i-> (T1_i=x_i; T2_i=y_i));
    apply(n,i-> T2_(i,i)=y_(i,i));
    T1 = matrix T1;
    T2 = matrix T2;
    p1:=flatten entries(A*F1-G1*T1);
    p2:=flatten entries(A*F2-G2*T2);
    Eqs:= p1|p2; 
    A1 := map(FFF^(2*n^2),FFF^(2*n^2),(i,j)->(Eqs#i)_(R_j));
    b1 := map(FFF^(2*n^2),FFF^1,(i,j)->-(Eqs#i)_(1_R));
    X := transpose solve(A1,b1);
    (sub(A, X), sub(T1, X), sub(T2, X))
    )
--------------------
--  Example:
--------------------
-- F1 = id_(FFF^4)
-- F2 = rsort id_(FFF^4)
-- G1 = random(FFF^4,FFF^4)
-- G2 = random(FFF^4,FFF^4)
-- 
-- moveFlags2Flags({F1,F2},{G1,G2})
-- o =(| .942485+.841897i -.453529+.038107i  -1.17023-1.18863i -.0211864+.39196i |,
--     | .033580+.866902i -.0844235-.340175i 1.06488-.119899i  .0185506+.411333i | 
--     | .725934+.355448i .229312+.274355i   -.467423+1.25503i -.195849+.736079i | 
--     | .542686+.238398i -.150172+.371548i  -1.36279+.224972i -.055652+.890821i | 
--    ------------------------------------------------------------------------------
--     | 1 -.584783+.236584i -2.07229-1.56411i -.628292-.794925i |, 
--     | 0 1                 1.4547+3.57843i   -.791082+1.93156i |  
--     | 0 0                 1                 .686317+.55597i   |  
--     | 0 0                 0                 1                 |  
--      ------------------------------------------------------------------------------
--     | .461031+.52935i .674426+3.90896i  .957904-.133557i  -1.95461-.07167i  |)
--     | 0               -1.98146-3.05206i -.619948+.386562i 3.38618+.656677i  |
--     | 0               0                 -.387966+.161397i -.064671+1.15621i |
--     | 0               0                 0                 .038901-4.54283i  |
--
--------------------

-------------------------
-- MovingFlag'at'Root 
-------------------------
-- function to create the moving flag node.FlagM
-- observed in the root of a Dag, after the specialization
-- in the checkerboard game.
-- this will be the same for every checkerboard Tree
-- and it is used to solve Internal Problem
------------------------
-- Example:
--
-- MovingFlag'at'Root 4
--  o =  | 1  1  1  1 |
--       | -1 -1 -1 0 |
--       | 1  1  0  0 |
--       | -1 0  0  0 |
------------------------
MovingFlag'at'Root = method(TypicalValue => Matrix)
MovingFlag'at'Root ZZ := n -> (
    M := mutableMatrix rsort id_(FFF^n);
    apply(0..n-1, i->(
	    apply(0..n-1-i, j->(
		    M_(i,j) = (-1)^i;
		    ));
	    ));
    matrix M
    )


-- NotAboveLambda
--
-- Function that, given a partition
-- Lambda, it computes the partitions
-- that are not above lambda in the Bruhat order
-------------------------------
-- Input:
--    l -- (List) the partition Lambda
--    k,n --ZZ,ZZ the Grassmannian Gr(k,n)
--
-- Output:
--    NotAbove  -- List of brackets b such that the 
--                 corresponding partition m is not above l 
--
----------------------------- 
-- Example:
-- 
-- the Bruhat order near the partition {2,1} in G(3,6) is:
--
--        /  \  |  / \ 
--    {1,1,1} {2,1}  {3}
--         \   /  \  /
--         {1,1}   {2}
--             \   /
--              {1}
--               |
--              { }
---------
-- notAboveLambda({2,1},3,6)
--  o = {{4, 5, 6}, {3, 5, 6}, {3, 4, 6}, 
--       {2, 5, 6}, {3, 4, 5}, {1, 5, 6}}
--
--  and these brackets corresponds to the partitions:
--      {{0, 0, 0}, {1, 0, 0}, {1, 1, 0}, 
--       {2, 0, 0}, {1, 1, 1}, {3, 0, 0}}
--
------- 
--  More examples in TST/tstNotAbove.m2
-----------------------------
notAboveLambda = method()
notAboveLambda(List,ZZ,ZZ) := (lambda,k,n) ->(
  -- We Assume that lambda is not the zero partition {0,0,...,0}
  -- k-#lambda is how many zeroes we have
  -- 0 is not a corner, so it needs to be deleted from L'
  L':=unique(delete(0,lambda));
  pos'corners:= apply(L', l->position(lambda, i->i==l, Reverse=>true));
  maxElements:=apply(pos'corners, i->(  --the maximal elements of the ordered set notAbove
	  toList(i:(n-k))|toList(k-i:lambda_i-1)
	  ));
  notAbove := new MutableHashTable;
  addPartition := la -> (
      b := sum la;
      if not notAbove#?b then notAbove#b = {la} 
      else if not member(la, notAbove#b)
      then notAbove#b = notAbove#b | {la}; 
      );
  scan(apply(maxElements, la->select(la,t->t!=0)), addPartition);
  i := max keys notAbove;
  while i>=0 do (
      scan(notAbove#i, la->
	  for j in 0..<#la do
	  if j==#la-1 or la#j>la#(j+1) 
	  then if j==#la-1 and la#j == 1 then addPartition drop(la,-1) 
	  else addPartition replace(j,la#j-1,la) 
	  );
      i = i - 1;
      );
  apply(flatten values notAbove, la->partition2bracket(la,k,n))
  )

---******************************---
------ For Pieri Homotopies ---------
---******************************----
---------------------------
--  skewSchubertVariety  --
-- Creates Matrix E_{m,l} --
---------------------------
-- option: Inputs, an integer or symbol; if integer then 

-- this line of code makes no sense and doesn't work:
-- if version#"VERSION" =!= "1.8.2.1" then inputGate = "inputGate"

skewSchubertVariety = method(TypicalValue=>Matrix, Options=>{Inputs=>53})
skewSchubertVariety(Sequence,List,List) := o->(kn,l,m)->(
     -- k and n are the integers defining the Grassmannian G(k,n)
     -- l and m are partitions of n
     (k,n):=kn;
     l = verifyLength(l, k);
     m = verifyLength(m, k);
     d := (k*(n-k)-sum(l)-sum(m));
     if instance(o.Inputs,ZZ) then R := FFF[vars(o.Inputs..d+o.Inputs-1)]; -- ring where the variables for the matrix lie
     r := 0;
     M := matrix (
	 for i from 1 to k list (
	     for j from 1 to n list (
		 if j==i+l_(k-i) then 1
		 else if j>i+l_(k-i) and j<=(n-k+i-m_(i-1)) then ( 
		     r=r+1; 
		     if instance(o.Inputs,ZZ) 
		     then R_(r-1) 
		     else inputGate (o.Inputs)_(r-1)
		     )
		 else 0
		 ) 
	     )    
	 );
     if instance(o.Inputs,ZZ) then M else 
     (M,toList apply(d,i->inputGate (o.Inputs)_i))
     )



----------------------
-- checkSchubertProblem
----------------------
-- Function that checks if a list of partitions or brackets
-- impose a feasible Schubert problem
----------------------
-- Input: 
--    conds - list of partitions or brackets
--    k,n   - integers that indicate the Grassmannian G(k,n)
-- Output:
--    none - if the partitions are good for a Schubert problem
--      or ERROR otherwise
--------------------------------------------------------------------
-- sanity check
--------------------------------------------------------------------
-- CAVEAT: if the user entered the conditions as brackets
--         it changes them into partitions and do the check
--------------------------------------------------------------------
checkSchubertProblem = method()
checkSchubertProblem (List,ZZ,ZZ) := (conds,k,n) -> (
    -- detect if conds are partitions or brackets and transforms them to partitions if not
    areAllBrackets:=apply(conds, c->(
	    if #c == k and c == sort unique c then true else false
	    ));
    if #unique(areAllBrackets) > 1 then (
	   error "verify your conditions: some seemed to be partitions some to be brackets"
    	) else if areAllBrackets_0 == true then(
	   conds = conds/(i-> bracket2partition(i,n)); -- we transform them into partitions
	);
    --------------
    scan(conds, c -> if #c > k or 
	c != rsort c or
	first c > n-k then error ("wrong partition: "|toString c|" verify your input")
	);
    if sum flatten conds != k*(n-k) then 
    error "sum of codimensions of partitions should equal the dimension of the Grassmannian";
    ) 

-----------------------------
--  checkSimpleSchubertProblem
-----------------------------
-- verify if the user gave a Simple Schubert Problem
-- the first two non-simple condition and the rest
-- should be the condition {1} and must add to dim Gr(k,n)
----------------------------
-- Input:
--    conds    - list of partitions {l,m,{1},...,{1}}
--    k,n      - integers specifying Gr(k,n)
-- Output:
--    none - if the Schubert problem is Simple
--    or ERROR otherwise
---------------------------
checkSimpleSchubertProblem = method()
checkSimpleSchubertProblem(List,ZZ,ZZ) := (conds,k,n) ->(    
    checkSchubertProblem(conds,k,n);
    simpleconds:= drop(conds,2);
    scan(simpleconds, c->(
	    if sum c != 1 then error (toString c| " is not a codimension one condition");
	    )); 
    )


--------------------------
-- verifyInput
-------------------------
-- Detects if the user gave partitions
-- or brackets to define Schubert conditions
-- checks if the input makes a feasible Schubert pblm
-- and if the flags are general
-------------------------
-- Input:
--    conds'flags - List of Schubert conditions with flags
--                  {(cond_List, flag_Matrix),...}
--
--    k,n         - integers defining Gr(k,n)
--
-- Output:
--    Pblm - List of Schubert conditions with flags
--            {(partition_List, flag_Matrix),...}
--    or ERROR - if the input was not correct
--------------------------
-- Note: Our methods assume you give Schubert
--       conditions as partitions and flags
--       as square invertible matrices
-------------------------
---------------
-- Examples in TST/tstVerifyInput.m2 
---------------

verifyInput = method()
verifyInput(List,ZZ,ZZ) := (conds'flags, k,n) ->(
    conds := conds'flags/first; -- list of Schubert conditions
    flags := conds'flags/last; -- list of flags
    -- check if these conditions impose a 0-dimensional Schubert Problem
    checkSchubertProblem(conds,k,n);
    --- Verify that the flags are square matrices of full rank
    scan(flags, F->(
	    if not instance(F,Matrix) or numColumns F != numRows F or abs(det F) < ERROR'TOLERANCE  then error(toString F|" should be an invertible square matrix of size "| toString n)	    
	    ));
    apply(#conds, i-> (conds_i, flags_i))
    )

----------------------
-- randomSchubertProblemInstance
----------------------
-- Creates a random instance of a Schubert problem 
-- by computing random matrices to specify the flags
----------------------
-- Input: 
--    conds - list of partitions
--    k,n   - integers that indicate the Grassmannian G(k,n)
--
--    Options:  Strategy => "unitary" : uses the Random Unitary Matrix from NAG4M2.
--                          "unit circle" : [default] creates a matrix whose entries are 
--                                           random complex numbers in the unit circle
-- Output:
--    a list of sequences of the from (cond_List,flag_Matrix)
--      where flag_Matrix is a random nxn matrix
------------------------
-- create an instance of a Schubert problem with random matrices specifying flags
randomSchubertProblemInstance = method(Options=>{Strategy=>"unit circle"})
randomSchubertProblemInstance (List,ZZ,ZZ) := o -> (conds,k,n) -> (
    checkSchubertProblem(conds,k,n);
    apply(conds, c->(c, 
	    if o.Strategy == "unitary" then randomUnitaryMatrix n else
	    if o.Strategy == "unit circle" then matrix table(n,n,(i,j)->exp(2*pi*ii*random RR))
	    else error "unknown strategy for random matrix"   
	    ))
    )