Skip to content

Commit

Permalink
Trac #18246: remove naive __hash__ from SageObject
Browse files Browse the repository at this point in the history
Hashing is a critical function in Python. In several places, objects do
use the generic `__hash__` from `SageObject` or a badly implemented one
that makes everything slow. For example:
 - #18215 for quadratic number field elements (in relation with
polyhedra #18241)
 - #18239 for permutation group elements

See also #19016 for a ticket with the same purpose (with `Element`
instead of `SageObject`).

URL: http://trac.sagemath.org/18246
Reported by: vdelecroix
Ticket author(s): Vincent Delecroix
Reviewer(s): Volker Braun, Nils Bruin
  • Loading branch information
Release Manager authored and vbraun committed Sep 7, 2015
2 parents 283c0fe + 5627a1d commit 4b26783
Show file tree
Hide file tree
Showing 62 changed files with 413 additions and 110 deletions.
10 changes: 10 additions & 0 deletions src/sage/algebras/commutative_dga.py
Original file line number Diff line number Diff line change
Expand Up @@ -2517,6 +2517,16 @@ def __init__(self, x):
"""
self._x = x

def __hash__(self):
r"""
TESTS::
sage: from sage.algebras.commutative_dga import CohomologyClass
sage: hash(CohomologyClass(sin)) == hash(sin)
True
"""
return hash(self._x)

def _repr_(self):
"""
EXAMPLES::
Expand Down
11 changes: 11 additions & 0 deletions src/sage/categories/functor.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,17 @@ cdef class Functor(SageObject):
self.__domain = domain
self.__codomain = codomain

def __hash__(self):
r"""
TESTS::
sage: from sage.categories.functor import Functor
sage: F = Functor(Rings(), Fields())
sage: hash(F) # random
42
"""
return hash(self.__domain) ^ hash(self.__codomain)

def __reduce__(self):
"""
Generic pickling of functors.
Expand Down
2 changes: 1 addition & 1 deletion src/sage/combinat/alternating_sign_matrix.py
Original file line number Diff line number Diff line change
Expand Up @@ -890,7 +890,7 @@ def left_key_as_permutation(self):
"""
return self.left_key().to_permutation()

class AlternatingSignMatrices(Parent, UniqueRepresentation):
class AlternatingSignMatrices(UniqueRepresentation, Parent):
r"""
Class of all `n \times n` alternating sign matrices.
Expand Down
1 change: 0 additions & 1 deletion src/sage/combinat/cluster_algebra_quiver/quiver.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
#*****************************************************************************
from sage.structure.sage_object import SageObject
from copy import copy
from sage.structure.unique_representation import UniqueRepresentation
from sage.misc.all import cached_method
from sage.rings.all import ZZ, CC, infinity
from sage.graphs.all import Graph, DiGraph
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1088,8 +1088,7 @@ def properties(self):
print '\t- elliptic: ', self.is_elliptic()


class QuiverMutationType_Irreducible(QuiverMutationType_abstract,
UniqueRepresentation, SageObject):
class QuiverMutationType_Irreducible(QuiverMutationType_abstract):
"""
The mutation type for a cluster algebra or a quiver. Should not be
called directly, but through QuiverMutationType.
Expand Down Expand Up @@ -1933,8 +1932,7 @@ def dual(self):
return self


class QuiverMutationType_Reducible(QuiverMutationType_abstract,
UniqueRepresentation, SageObject):
class QuiverMutationType_Reducible(QuiverMutationType_abstract):
"""
The mutation type for a cluster algebra or a quiver. Should not be
called directly, but through QuiverMutationType. Inherits from
Expand Down
2 changes: 1 addition & 1 deletion src/sage/combinat/composition.py
Original file line number Diff line number Diff line change
Expand Up @@ -1308,7 +1308,7 @@ def wll_gt(self, co2):

##############################################################

class Compositions(Parent, UniqueRepresentation):
class Compositions(UniqueRepresentation, Parent):
r"""
Set of integer compositions.
Expand Down
2 changes: 1 addition & 1 deletion src/sage/combinat/crystals/affinization.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
from sage.categories.infinite_enumerated_sets import InfiniteEnumeratedSets
from sage.rings.infinity import Infinity

class AffinizationOfCrystal(Parent, UniqueRepresentation):
class AffinizationOfCrystal(UniqueRepresentation, Parent):
r"""
An affiniziation of a crystal.
Expand Down
8 changes: 4 additions & 4 deletions src/sage/combinat/crystals/elementary_crystals.py
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ def f(self,i):
"""
return None

class TCrystal(Parent, UniqueRepresentation):
class TCrystal(UniqueRepresentation, Parent):
r"""
The crystal `T_{\lambda}`.
Expand Down Expand Up @@ -416,7 +416,7 @@ def weight(self):
"""
return self.parent()._weight

class RCrystal(Parent, UniqueRepresentation):
class RCrystal(UniqueRepresentation, Parent):
r"""
The crystal `R_{\lambda}`.
Expand Down Expand Up @@ -672,7 +672,7 @@ def weight(self):
"""
return self.parent()._weight

class ElementaryCrystal(Parent, UniqueRepresentation):
class ElementaryCrystal(UniqueRepresentation, Parent):
r"""
The elementary crystal `B_i`.
Expand Down Expand Up @@ -986,7 +986,7 @@ def weight(self):
Q = self.parent().weight_lattice_realization()
return self._m * Q.simple_root(self.parent()._i)

class ComponentCrystal(Parent,UniqueRepresentation):
class ComponentCrystal(UniqueRepresentation, Parent):
r"""
The component crystal.
Expand Down
2 changes: 1 addition & 1 deletion src/sage/combinat/crystals/generalized_young_walls.py
Original file line number Diff line number Diff line change
Expand Up @@ -641,7 +641,7 @@ def in_highest_weight_crystal(self,La):
return True


class InfinityCrystalOfGeneralizedYoungWalls(Parent,UniqueRepresentation):
class InfinityCrystalOfGeneralizedYoungWalls(UniqueRepresentation, Parent):
r"""
The crystal `\mathcal{Y}(\infty)` of generalized Young walls of
type `A_n^{(1)}` as defined in [KS10]_.
Expand Down
4 changes: 2 additions & 2 deletions src/sage/combinat/crystals/induced_structure.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
from sage.structure.parent import Parent
from sage.structure.element_wrapper import ElementWrapper

class InducedCrystal(Parent, UniqueRepresentation):
class InducedCrystal(UniqueRepresentation, Parent):
r"""
A crystal induced from an injection.
Expand Down Expand Up @@ -396,7 +396,7 @@ def weight(self):
"""
return self.parent()._phi(self.value).weight()

class InducedFromCrystal(Parent, UniqueRepresentation):
class InducedFromCrystal(UniqueRepresentation, Parent):
r"""
A crystal induced from an injection.
Expand Down
2 changes: 1 addition & 1 deletion src/sage/combinat/crystals/monomial_crystals.py
Original file line number Diff line number Diff line change
Expand Up @@ -759,7 +759,7 @@ def f(self,i):
d[(i,kf)] = d.get((i,kf),0) - 1
return self.__class__(self.parent(), d)

class InfinityCrystalOfNakajimaMonomials(Parent,UniqueRepresentation):
class InfinityCrystalOfNakajimaMonomials(UniqueRepresentation, Parent):
r"""
Let `Y_{i,k}`, for `i \in I` and `k \in \ZZ`, be a commuting set of
variables, and let `\boldsymbol{1}` be a new variable which commutes with
Expand Down
2 changes: 1 addition & 1 deletion src/sage/combinat/crystals/subcrystal.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
from sage.rings.integer import Integer
from sage.rings.infinity import infinity

class Subcrystal(Parent, UniqueRepresentation):
class Subcrystal(UniqueRepresentation, Parent):
"""
A subcrystal `X` of an ambient crystal `Y` is a crystal formed by taking a
subset of `Y` and whose crystal structure is induced by `Y`.
Expand Down
2 changes: 1 addition & 1 deletion src/sage/combinat/derangements.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ def to_permutation(self):
raise ValueError("Can only convert to a permutation for derangements of [1, 2, ..., n]")
return Permutation(list(self))

class Derangements(Parent, UniqueRepresentation):
class Derangements(UniqueRepresentation, Parent):
r"""
The class of all derangements of a set or multiset.
Expand Down
2 changes: 1 addition & 1 deletion src/sage/combinat/descent_algebra.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
from sage.combinat.symmetric_group_algebra import SymmetricGroupAlgebra
from sage.combinat.ncsf_qsym.ncsf import NonCommutativeSymmetricFunctions

class DescentAlgebra(Parent, UniqueRepresentation):
class DescentAlgebra(UniqueRepresentation, Parent):
r"""
Solomon's descent algebra.
Expand Down
2 changes: 1 addition & 1 deletion src/sage/combinat/dyck_word.py
Original file line number Diff line number Diff line change
Expand Up @@ -3102,7 +3102,7 @@ def to_alternating_sign_matrix(self):
return A.from_monotone_triangle(monotone_triangle)


class DyckWords(Parent, UniqueRepresentation):
class DyckWords(UniqueRepresentation, Parent):
r"""
Dyck words.
Expand Down
2 changes: 1 addition & 1 deletion src/sage/combinat/gelfand_tsetlin_patterns.py
Original file line number Diff line number Diff line change
Expand Up @@ -507,7 +507,7 @@ def Tokuyama_coefficient(self, name='t'):
return (t+1)**(self.number_of_special_entries()) * t**(self.number_of_boxes())


class GelfandTsetlinPatterns(Parent, UniqueRepresentation):
class GelfandTsetlinPatterns(UniqueRepresentation, Parent):
"""
Gelfand-Tsetlin patterns.
Expand Down
2 changes: 1 addition & 1 deletion src/sage/combinat/partition.py
Original file line number Diff line number Diff line change
Expand Up @@ -6830,7 +6830,7 @@ def _repr_(self):
# Partitions Greatest EQ #
##########################

class PartitionsGreatestEQ(IntegerListsLex, UniqueRepresentation):
class PartitionsGreatestEQ(UniqueRepresentation, IntegerListsLex):
"""
The class of all (unordered) "restricted" partitions of the integer `n`
having its greatest part equal to the integer `k`.
Expand Down
2 changes: 1 addition & 1 deletion src/sage/combinat/permutation.py
Original file line number Diff line number Diff line change
Expand Up @@ -4834,7 +4834,7 @@ def shifted_shuffle(self, other):
################################################################

# Base class for permutations
class Permutations(Parent, UniqueRepresentation):
class Permutations(UniqueRepresentation, Parent):
r"""
Permutations.
Expand Down
4 changes: 2 additions & 2 deletions src/sage/combinat/ribbon_tableau.py
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ def to_word(self):
# Ribbon Tableaux #
#####################

class RibbonTableaux(Parent, UniqueRepresentation):
class RibbonTableaux(UniqueRepresentation, Parent):
r"""
Ribbon tableaux.
Expand Down Expand Up @@ -952,7 +952,7 @@ def _inversion_pairs_from_position(self, k, ij):
return res


class MultiSkewTableaux(Parent, UniqueRepresentation):
class MultiSkewTableaux(UniqueRepresentation, Parent):
r"""
Multiskew tableaux.
"""
Expand Down
2 changes: 1 addition & 1 deletion src/sage/combinat/rigged_configurations/kleber_tree.py
Original file line number Diff line number Diff line change
Expand Up @@ -469,7 +469,7 @@ def _latex_(self):
# Kleber tree classes #
#######################

class KleberTree(Parent, UniqueRepresentation):
class KleberTree(UniqueRepresentation, Parent):
r"""
The tree that is generated by Kleber's algorithm.
Expand Down
2 changes: 1 addition & 1 deletion src/sage/combinat/rigged_configurations/rc_crystal.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
from sage.combinat.rigged_configurations.rigged_partition import RiggedPartition

# Note on implementation, this class is used for simply-laced types only
class CrystalOfRiggedConfigurations(Parent, UniqueRepresentation):
class CrystalOfRiggedConfigurations(UniqueRepresentation, Parent):
r"""
A highest weight crystal of rigged configurations.
Expand Down
2 changes: 1 addition & 1 deletion src/sage/combinat/rigged_configurations/rc_infinity.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
from sage.combinat.rigged_configurations.rigged_partition import RiggedPartition

# Note on implementation, this class is used for simply-laced types only
class InfinityCrystalOfRiggedConfigurations(Parent, UniqueRepresentation):
class InfinityCrystalOfRiggedConfigurations(UniqueRepresentation, Parent):
r"""
Rigged configuration model for `\mathcal{B}(\infty)`.
Expand Down
22 changes: 14 additions & 8 deletions src/sage/combinat/rigged_configurations/rigged_configurations.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ def KirillovReshetikhinCrystal(cartan_type, r, s):
return RiggedConfigurations(cartan_type, [[r,s]])

# Note on implementation, this class is used for simply-laced types only
class RiggedConfigurations(Parent, UniqueRepresentation):
class RiggedConfigurations(UniqueRepresentation, Parent):
r"""
Rigged configurations as `U_q^{\prime}(\mathfrak{g})`-crystals.
Expand Down Expand Up @@ -249,7 +249,7 @@ class RiggedConfigurations(Parent, UniqueRepresentation):
6
sage: len(RC.list()) == RC.cardinality()
True
sage: RC.list()
sage: RC.list() # random
[
<BLANKLINE>
0[ ]0
Expand Down Expand Up @@ -489,11 +489,11 @@ def __iter__(self):
<BLANKLINE>
(/)
<BLANKLINE>
sage: next(g)
sage: next(g) # random
<BLANKLINE>
(/)
0[ ]0
<BLANKLINE>
-1[ ]-1
0[ ]0
<BLANKLINE>
(/)
<BLANKLINE>
Expand Down Expand Up @@ -858,12 +858,18 @@ def cardinality(self):
sage: RC = RiggedConfigurations(['A', 3, 1], [[3, 2], [1, 2]])
sage: RC.cardinality()
100
sage: RC = RiggedConfigurations(['B', 3, 1], [[2,2],[1,2]])
sage: RC.cardinality()
5130
sage: len(RC.list())
100
sage: RC = RiggedConfigurations(['E', 7, 1], [[1,1]])
sage: RC.cardinality()
134
sage: len(RC.list())
134
sage: RC = RiggedConfigurations(['B', 3, 1], [[2,2],[1,2]])
sage: RC.cardinality()
5130
"""
CWLR = self.cartan_type().classical().root_system().ambient_space()
return sum(CWLR.weyl_dimension(mg.classical_weight()) for mg in self.module_generators)
Expand Down
13 changes: 12 additions & 1 deletion src/sage/combinat/root_system/hecke_algebra_representation.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,15 @@
import functools
from sage.misc.abstract_method import abstract_method
from sage.misc.cachefunc import cached_method
from sage.misc.fast_methods import WithEqualityById
from sage.structure.sage_object import SageObject
from sage.structure.unique_representation import UniqueRepresentation
from sage.sets.family import Family
from sage.combinat.subset import Subsets
from sage.rings.infinity import infinity
from sage.rings.integer_ring import ZZ

class HeckeAlgebraRepresentation(SageObject):
class HeckeAlgebraRepresentation(WithEqualityById, SageObject):
r"""
A representation of an (affine) Hecke algebra given by the action of the `T` generators
Expand Down Expand Up @@ -64,6 +65,16 @@ class HeckeAlgebraRepresentation(SageObject):
sage: H.Y()
Lazy family (...)_{i in Coroot lattice of the Root system of type ['A', 3, 1]}
TESTS::
sage: from sage.combinat.root_system.hecke_algebra_representation import HeckeAlgebraRepresentation
sage: W = SymmetricGroup(3)
sage: domain = W.algebra(QQ)
sage: action = lambda x,i: domain.monomial(x.apply_simple_reflection(i, side="right"))
sage: r = HeckeAlgebraRepresentation(domain, action, CartanType(["A",2]), 1, -1)
sage: hash(r) # random
3
REFERENCES:
.. [HST2008] F. Hivert, A. Schilling, N. Thiery,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
from sage.combinat.root_system.weyl_characters import WeylCharacterRing

# TODO: Make this a proper parent and implement actions
class IntegrableRepresentation(CategoryObject, UniqueRepresentation):
class IntegrableRepresentation(UniqueRepresentation, CategoryObject):
r"""
An irreducible integrable highest weight representation of
an affine Lie algebra.
Expand Down
5 changes: 5 additions & 0 deletions src/sage/combinat/root_system/root_system.py
Original file line number Diff line number Diff line change
Expand Up @@ -447,6 +447,11 @@ def __cmp__(self, other):
True
sage: r1 == r2
False
Check that they inherit a hash method from ``UniqueRepresentation``::
sage: hash(r1) # random
42
"""
if self.__class__ != other.__class__:
return cmp(self.__class__, other.__class__)
Expand Down
4 changes: 3 additions & 1 deletion src/sage/combinat/root_system/type_folded.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
from sage.sets.family import Family
from sage.combinat.root_system.cartan_type import CartanType

class CartanTypeFolded(SageObject, UniqueRepresentation):
class CartanTypeFolded(UniqueRepresentation, SageObject):
r"""
A Cartan type realized from a (Dynkin) diagram folding.
Expand Down Expand Up @@ -193,6 +193,8 @@ def __init__(self, cartan_type, folding_of, orbit):
sage: fct = CartanType(['C',4,1]).as_folding()
sage: TestSuite(fct).run()
sage: hash(fct) # random
42
"""
self._cartan_type = cartan_type
self._folding = folding_of
Expand Down

0 comments on commit 4b26783

Please sign in to comment.