118
118
advertise yet another way to pass values to FindStat::
119
119
120
120
sage: r = findstat(Permutations, lambda pi: pi.saliances()[0], depth=2); r # optional -- internet
121
- 0: St000740oMp00087 with offset 1 (quality [100, 100])
121
+ 0: St000740oMp00066 with offset 1 (quality [100, 100])
122
+ 1: St000740oMp00087 with offset 1 (quality [100, 100])
122
123
...
123
124
124
125
Note that some of the matches are up to a global offset. For
125
126
example, we have::
126
127
127
- sage: r[0 ].info() # optional -- internet
128
+ sage: r[1 ].info() # optional -- internet
128
129
after adding 1 to every value
129
130
and applying
130
131
Mp00087: inverse first fundamental transformation: Permutations -> Permutations
@@ -221,7 +222,6 @@ def mapping(sigma):
221
222
from sage .databases .oeis import FancyTuple
222
223
223
224
from ast import literal_eval
224
- from collections import OrderedDict
225
225
from copy import deepcopy
226
226
import re
227
227
import webbrowser
@@ -256,7 +256,7 @@ def mapping(sigma):
256
256
from sage .combinat .words .word import Word
257
257
from sage .combinat .words .words import Words
258
258
from sage .combinat .words .abstract_word import Word_class
259
- from sage .combinat .colored_permutations import SignedPermutations
259
+ from sage .combinat .colored_permutations import SignedPermutation , SignedPermutations
260
260
from sage .combinat .plane_partition import PlanePartition
261
261
from sage .combinat .decorated_permutation import DecoratedPermutation , DecoratedPermutations
262
262
@@ -431,10 +431,10 @@ def _get_json(url, **kwargs):
431
431
EXAMPLES::
432
432
433
433
sage: from sage.databases.findstat import _get_json, FINDSTAT_API_MAPS
434
- sage: _get_json(FINDSTAT_API_MAPS + "?xxx =yyy") # optional -- internet
434
+ sage: _get_json(FINDSTAT_API_MAPS + "?fields =yyy") # optional -- internet
435
435
Traceback (most recent call last):
436
436
...
437
- ValueError: E005: On filtering maps, the following parameters are not allowed : [u'xxx'].
437
+ ValueError: E018: Unknown fields in Map, Combinatorial map: to semistandard tableau via monotone triangles : ['yyy']
438
438
"""
439
439
response = requests .get (url )
440
440
if response .ok :
@@ -454,10 +454,10 @@ def _post_json(url, data, **kwargs):
454
454
EXAMPLES::
455
455
456
456
sage: from sage.databases.findstat import _post_json, FINDSTAT_API_STATISTICS
457
- sage: _post_json(FINDSTAT_API_STATISTICS, {"xxx ": "yyy"}) # optional -- internet
457
+ sage: _post_json(FINDSTAT_API_STATISTICS, {"fields ": "yyy"}) # optional -- internet
458
458
Traceback (most recent call last):
459
459
...
460
- ValueError: E005: On filtering statistics, the following parameters are not allowed : ['xxx'].
460
+ ValueError: E018: Unknown fields in Statistic, Combinatorial statistic: St000001 : ['yyy']
461
461
"""
462
462
response = requests .post (url , data = data )
463
463
if response .ok :
@@ -1007,7 +1007,9 @@ def findstat(query=None, values=None, distribution=None, domain=None,
1007
1007
sage: findstat((PM, [1 for m in PM])) # optional -- internet
1008
1008
Traceback (most recent call last):
1009
1009
...
1010
- ValueError: E016: You passed too few elements (0 < 3) to FindStat!
1010
+ ValueError: E016: The statistic finder was unable to perform a search on your data. The following errors have occured:
1011
+ <BLANKLINE>
1012
+ You passed too few elements (0 < 3) to FindStat!
1011
1013
1012
1014
Finally, we can also retrieve all statistics with a given domain::
1013
1015
@@ -1852,7 +1854,7 @@ def first_terms(self):
1852
1854
if self ._first_terms_cache is None :
1853
1855
self ._first_terms_cache = self ._fetch_first_terms ()
1854
1856
# a shallow copy suffices - tuples are immutable
1855
- return OrderedDict (self ._first_terms_cache )
1857
+ return dict (self ._first_terms_cache )
1856
1858
1857
1859
def _first_terms_raw (self , max_values ):
1858
1860
"""
@@ -2655,11 +2657,11 @@ def first_terms(self, max_values=FINDSTAT_MAX_SUBMISSION_VALUES):
2655
2657
0: St000041 (quality [99, 100])
2656
2658
1: St000042 (quality [99, 100])
2657
2659
sage: r.first_terms() # optional -- internet
2658
- OrderedDict([([], 0), ( [(1, 2)], 0)])
2660
+ {[]: 0, [(1, 2)]: 0}
2659
2661
"""
2660
- return OrderedDict (itertools .islice (((objs [0 ], vals [0 ])
2661
- for objs , vals in self ._known_terms
2662
- if len (vals ) == 1 ), max_values ))
2662
+ return dict (itertools .islice (((objs [0 ], vals [0 ])
2663
+ for objs , vals in self ._known_terms
2664
+ if len (vals ) == 1 ), max_values ))
2663
2665
2664
2666
def _first_terms_raw (self , max_values ):
2665
2667
"""
@@ -2693,7 +2695,7 @@ def _generating_functions_dict(self,
2693
2695
sage: q = findstat(data, depth=0); q # optional -- internet
2694
2696
0: St000054 (quality [100, 100])
2695
2697
sage: q.first_terms() # optional -- internet
2696
- OrderedDict([([ 1, 2], 1)])
2698
+ {[ 1, 2]: 1}
2697
2699
sage: q.generating_functions() # optional -- internet, indirect doctest
2698
2700
{3: 2*q^3 + 2*q^2 + 2*q}
2699
2701
"""
@@ -4232,7 +4234,7 @@ def levels_with_sizes(self):
4232
4234
sage: from sage.databases.findstat import FindStatCollection
4233
4235
sage: cc = FindStatCollection("Perfect Matchings") # optional -- internet
4234
4236
sage: cc.levels_with_sizes() # optional -- internet
4235
- OrderedDict([(2, 1), (4, 3), (6, 15), (8, 105), (10, 945)])
4237
+ {2: 1, 4: 3, 6: 15, 8: 105, 10: 945}
4236
4238
"""
4237
4239
return self ._data ["LevelsWithSizes" ]
4238
4240
@@ -4486,8 +4488,10 @@ def name(self, style="singular"):
4486
4488
"element_to_string" ,
4487
4489
"elements_on_level" , # return all elements on given level
4488
4490
"element_level" , # return level of a given element
4489
- "is_element" ]) # return whether element is member of this collection (and, ideally, of no other collection)
4491
+ "is_element" ]) # return whether element is member of this collection
4490
4492
4493
+ # this dictionary must be sorted so that subclasses come before
4494
+ # superclasses, eg., "StandardTableaux" before "SemistandardTableaux"
4491
4495
_SupportedFindStatCollections = {
4492
4496
"Permutations" :
4493
4497
_SupportedFindStatCollection (lambda x : Permutation (literal_eval (x )),
@@ -4501,7 +4505,6 @@ def name(self, style="singular"):
4501
4505
lambda x : Words ([0 ,1 ], length = x ),
4502
4506
lambda x : x .length (),
4503
4507
lambda x : isinstance (x , Word_class )),
4504
-
4505
4508
"AlternatingSignMatrices" :
4506
4509
_SupportedFindStatCollection (lambda x : AlternatingSignMatrix (literal_eval (x )),
4507
4510
lambda x : str (list (map (list , x .to_matrix ().rows ()))),
@@ -4549,18 +4552,18 @@ def name(self, style="singular"):
4549
4552
lambda x : (g .copy (immutable = True ) for g in graphs (x , copy = False )),
4550
4553
lambda x : x .num_verts (),
4551
4554
lambda x : isinstance (x , Graph )),
4552
- "IntegerCompositions" :
4553
- _SupportedFindStatCollection (lambda x : Composition (literal_eval (x )),
4554
- str ,
4555
- Compositions ,
4556
- lambda x : x .size (),
4557
- lambda x : isinstance (x , Composition )),
4558
4555
"IntegerPartitions" :
4559
4556
_SupportedFindStatCollection (lambda x : Partition (literal_eval (x )),
4560
4557
str ,
4561
4558
Partitions ,
4562
4559
lambda x : x .size (),
4563
4560
lambda x : isinstance (x , Partition )),
4561
+ "IntegerCompositions" :
4562
+ _SupportedFindStatCollection (lambda x : Composition (literal_eval (x )),
4563
+ str ,
4564
+ Compositions ,
4565
+ lambda x : x .size (),
4566
+ lambda x : isinstance (x , Composition )),
4564
4567
"OrderedTrees" :
4565
4568
_SupportedFindStatCollection (lambda x : OrderedTree (literal_eval (x )),
4566
4569
str ,
@@ -4573,12 +4576,13 @@ def name(self, style="singular"):
4573
4576
ParkingFunctions ,
4574
4577
len ,
4575
4578
lambda x : isinstance (x , ParkingFunction )),
4576
- "PerfectMatchings" :
4577
- _SupportedFindStatCollection (lambda x : PerfectMatching (literal_eval (x )),
4578
- str ,
4579
- PerfectMatchings ,
4580
- lambda x : x .size (),
4581
- lambda x : isinstance (x , PerfectMatching )),
4579
+ "Lattices" :
4580
+ _SupportedFindStatCollection (lambda x : (lambda R , E : LatticePoset ((list (range (E )), R )))(* literal_eval (x )),
4581
+ lambda X : str ((sorted (X ._hasse_diagram .cover_relations ()),
4582
+ len (X ._hasse_diagram .vertices (sort = False )))),
4583
+ _finite_lattices ,
4584
+ lambda x : x .cardinality (),
4585
+ lambda x : isinstance (x , FiniteLatticePoset )),
4582
4586
"Posets" :
4583
4587
_SupportedFindStatCollection (lambda x : (lambda R , E : Poset ((list (range (E )), R )))(* literal_eval (x )),
4584
4588
lambda X : str ((sorted (X ._hasse_diagram .cover_relations ()),
@@ -4592,13 +4596,19 @@ def name(self, style="singular"):
4592
4596
StandardTableaux ,
4593
4597
lambda x : x .size (),
4594
4598
lambda x : isinstance (x , StandardTableau )),
4595
- "SemistandardTableaux" : # apparently, isinstance(x, SemistandardTableau) is True for StandardTableaux x
4599
+ "SemistandardTableaux" :
4596
4600
_SupportedFindStatCollection (lambda x : SemistandardTableau (literal_eval (x )),
4597
4601
str ,
4598
4602
lambda x : (T for T in SemistandardTableaux (size = x [0 ], max_entry = x [1 ])
4599
4603
if max (T .entries ()) == x [1 ]),
4600
4604
lambda x : (x .size (), max (x .entries ())),
4601
- lambda x : isinstance (x , SemistandardTableau ) and not isinstance (x , StandardTableau )),
4605
+ lambda x : isinstance (x , SemistandardTableau )),
4606
+ "PerfectMatchings" :
4607
+ _SupportedFindStatCollection (lambda x : PerfectMatching (literal_eval (x )),
4608
+ str ,
4609
+ PerfectMatchings ,
4610
+ lambda x : x .size (),
4611
+ lambda x : isinstance (x , PerfectMatching )),
4602
4612
"SetPartitions" :
4603
4613
_SupportedFindStatCollection (lambda x : SetPartition (literal_eval (x .replace ('{' ,'[' ).replace ('}' ,']' ))),
4604
4614
str ,
@@ -4616,7 +4626,7 @@ def name(self, style="singular"):
4616
4626
str ,
4617
4627
SignedPermutations ,
4618
4628
lambda x : len (list (x )),
4619
- lambda x : isinstance (x , SignedPermutations . Element )),
4629
+ lambda x : isinstance (x , SignedPermutation )),
4620
4630
"PlanePartitions" :
4621
4631
_SupportedFindStatCollection (lambda x : PlanePartition (literal_eval (x )),
4622
4632
lambda X : str (list (X )).replace (" " ,"" ),
@@ -4630,14 +4640,7 @@ def name(self, style="singular"):
4630
4640
for i , v in enumerate (x , 1 ))) + "]" ,
4631
4641
DecoratedPermutations ,
4632
4642
lambda x : x .size (),
4633
- lambda x : isinstance (x , DecoratedPermutation )),
4634
- "Lattices" :
4635
- _SupportedFindStatCollection (lambda x : (lambda R , E : LatticePoset ((list (range (E )), R )))(* literal_eval (x )),
4636
- lambda X : str ((sorted (X ._hasse_diagram .cover_relations ()),
4637
- len (X ._hasse_diagram .vertices (sort = False )))),
4638
- _finite_lattices ,
4639
- lambda x : x .cardinality (),
4640
- lambda x : isinstance (x , FiniteLatticePoset ))}
4643
+ lambda x : isinstance (x , DecoratedPermutation ))}
4641
4644
4642
4645
4643
4646
class FindStatCollections (UniqueRepresentation , Parent ):
@@ -4689,11 +4692,10 @@ def __init__(self):
4689
4692
"""
4690
4693
fields = "LevelsWithSizes,Name,NamePlural,NameWiki"
4691
4694
url = FINDSTAT_API_COLLECTIONS + "?fields=" + fields
4692
- d = _get_json (url , object_pairs_hook = OrderedDict )
4693
- self ._findstat_collections = d ["included" ]["Collections" ]
4694
- for id , data in self ._findstat_collections .items ():
4695
- data ["LevelsWithSizes" ] = OrderedDict ((literal_eval (level ), size )
4696
- for level , size in data ["LevelsWithSizes" ].items ())
4695
+ d = _get_json (url , object_pairs_hook = dict )["included" ]["Collections" ]
4696
+ for id , data in d .items ():
4697
+ data ["LevelsWithSizes" ] = {literal_eval (level ): size
4698
+ for level , size in data ["LevelsWithSizes" ].items ()}
4697
4699
if data ["NameWiki" ] in _SupportedFindStatCollections :
4698
4700
data ["Code" ] = _SupportedFindStatCollections [data ["NameWiki" ]]
4699
4701
else :
@@ -4706,7 +4708,13 @@ def __init__(self):
4706
4708
# fields = "SageCodeElementToString,SageCodeElementsOnLevel,SageCodeStringToElement"
4707
4709
# url = FINDSTAT_API_COLLECTIONS + id + "?fields=" + fields
4708
4710
# print(json.load(urlopen(url))["included"]["Collections"][id])
4711
+ def position (item ):
4712
+ try :
4713
+ return tuple (_SupportedFindStatCollections ).index (item [1 ]["NameWiki" ])
4714
+ except ValueError :
4715
+ return len (_SupportedFindStatCollections )
4709
4716
4717
+ self ._findstat_collections = dict (sorted (d .items (), key = position ))
4710
4718
Parent .__init__ (self , category = Sets ())
4711
4719
4712
4720
def _element_constructor_ (self , entry ):
@@ -4733,7 +4741,6 @@ def _element_constructor_(self, entry):
4733
4741
Cc0012: Perfect matchings,
4734
4742
Cc0013: Cores,
4735
4743
Cc0014: Posets,
4736
- Cc0014: Posets,
4737
4744
Cc0017: Alternating sign matrices,
4738
4745
Cc0018: Gelfand-Tsetlin patterns,
4739
4746
Cc0019: Semistandard tableaux,
@@ -4745,7 +4752,8 @@ def _element_constructor_(self, entry):
4745
4752
Cc0025: Plane partitions,
4746
4753
Cc0026: Decorated permutations,
4747
4754
Cc0027: Signed permutations,
4748
- Cc0028: Skew partitions]
4755
+ Cc0028: Skew partitions,
4756
+ Cc0029: Lattices]
4749
4757
4750
4758
sage: FindStatCollection(Permutation([1,2,3])) # optional -- internet
4751
4759
Cc0001: Permutations
@@ -4775,6 +4783,13 @@ def _element_constructor_(self, entry):
4775
4783
4776
4784
sage: len(cc.first_terms(lambda x: x.edges(labels=False, sort=False)).list()) # optional -- internet
4777
4785
4
4786
+
4787
+ Check that we can override the automatic detection::
4788
+
4789
+ sage: l = [(T, len(T)) for n in range(1,5) for T in StandardTableaux(n)] # optional -- internet
4790
+ sage: qu = findstat("Semistandardtableaux", l, depth=1) # optional -- internet
4791
+ sage: qu[0] # optional -- internet
4792
+ St000010oMp00077 (quality [100, 100])
4778
4793
"""
4779
4794
if isinstance (entry , self .Element ):
4780
4795
return entry
0 commit comments