def __init__(self, cartan_type): """ Construct this Coxeter group as a Sage permutation group, by fetching the permutation representation of the generators from Chevie's database. TESTS:: sage: from sage.combinat.root_system.coxeter_group import CoxeterGroupAsPermutationGroup sage: W = CoxeterGroupAsPermutationGroup(CartanType(["H",3])) # optional - chevie sage: TestSuite(W).run() # optional - chevie """ assert cartan_type.is_finite() assert cartan_type.is_irreducible() self._semi_simple_rank = cartan_type.n from sage.interfaces.gap3 import gap3 gap3._start() gap3.load_package("chevie") self._gap_group = gap3('CoxeterGroup("%s",%s)'%(cartan_type.letter,cartan_type.n)) # Following #9032, x.N is an alias for x.numerical_approx in every Sage object ... N = self._gap_group.__getattr__("N").sage() generators = [str(x) for x in self._gap_group.generators] self._is_positive_root = [None] + [ True ] * N + [False]*N PermutationGroup_generic.__init__(self, gens = generators, category = Category.join([FinitePermutationGroups(), FiniteCoxeterGroups()]))
def __init__(self, cartan_type): """ Construct this Coxeter group as a Sage permutation group, by fetching the permutation representation of the generators from Chevie's database. TESTS:: sage: from sage.combinat.root_system.coxeter_group import CoxeterGroupAsPermutationGroup sage: W = CoxeterGroupAsPermutationGroup(CartanType(["H",3])) # optional - chevie sage: TestSuite(W).run() # optional - chevie """ assert cartan_type.is_finite() assert cartan_type.is_irreducible() self._semi_simple_rank = cartan_type.n from sage.interfaces.gap3 import gap3 gap3._start() gap3.load_package("chevie") self._gap_group = gap3('CoxeterGroup("%s",%s)' % (cartan_type.letter, cartan_type.n)) # Following #9032, x.N is an alias for x.numerical_approx in every Sage object ... N = self._gap_group.__getattr__("N").sage() generators = [str(x) for x in self._gap_group.generators] self._is_positive_root = [None] + [True] * N + [False] * N PermutationGroup_generic.__init__(self, gens=generators, category=Category.join([ FinitePermutationGroups(), FiniteCoxeterGroups() ]))
def is_chevie_available(): r""" Tests whether the GAP3 Chevie package is available EXAMPLES:: sage: from sage.combinat.root_system.coxeter_group import is_chevie_available sage: is_chevie_available() # random False sage: is_chevie_available() in [True, False] True """ try: from sage.interfaces.gap3 import gap3 gap3._start() gap3.load_package("chevie") return True except Exception: return False
def ReflectionGroup(*args, **kwds): r""" Construct a finite (complex or real) reflection group as a Sage permutation group by fetching the permutation representation of the generators from chevie's database. INPUT: can be one or multiple of the following: - a triple `(r, p, n)` with `p` divides `r`, which denotes the group `G(r, p, n)` - an integer between `4` and `37`, which denotes an exceptional irreducible complex reflection group - a finite Cartan-Killing type EXAMPLES: Finite reflection groups can be constructed from Cartan-Killing classification types:: sage: W = ReflectionGroup(['A',3]); W # optional - gap3 Irreducible real reflection group of rank 3 and type A3 sage: W = ReflectionGroup(['H',4]); W # optional - gap3 Irreducible real reflection group of rank 4 and type H4 sage: W = ReflectionGroup(['I',5]); W # optional - gap3 Irreducible real reflection group of rank 2 and type I2(5) the complex infinite family `G(r,p,n)` with `p` divides `r`:: sage: W = ReflectionGroup((1,1,4)); W # optional - gap3 Irreducible real reflection group of rank 3 and type A3 sage: W = ReflectionGroup((2,1,3)); W # optional - gap3 Irreducible real reflection group of rank 3 and type B3 Chevalley-Shepard-Todd exceptional classification types:: sage: W = ReflectionGroup(23); W # optional - gap3 Irreducible real reflection group of rank 3 and type H3 Cartan types and matrices:: sage: ReflectionGroup(CartanType(['A',2])) # optional - gap3 Irreducible real reflection group of rank 2 and type A2 sage: ReflectionGroup(CartanType((['A',2],['A',2]))) # optional - gap3 Reducible real reflection group of rank 4 and type A2 x A2 sage: C = CartanMatrix(['A',2]) # optional - gap3 sage: ReflectionGroup(C) # optional - gap3 Irreducible real reflection group of rank 2 and type A2 multiples of the above:: sage: W = ReflectionGroup(['A',2],['B',2]); W # optional - gap3 Reducible real reflection group of rank 4 and type A2 x B2 sage: W = ReflectionGroup(['A',2],4); W # optional - gap3 Reducible complex reflection group of rank 4 and type A2 x ST4 sage: W = ReflectionGroup((4,2,2),4); W # optional - gap3 Reducible complex reflection group of rank 4 and type G(4,2,2) x ST4 """ if not is_chevie_available(): raise ImportError("the GAP3 package 'chevie' is needed to work with (complex) reflection groups") gap3.load_package("chevie") error_msg = "the input data (%s) is not valid for reflection groups" W_types = [] is_complex = False for arg in args: # preparsing if isinstance(arg, list): X = tuple(arg) else: X = arg # precheck for valid input data if not (isinstance(X, (CartanType_abstract, tuple)) or (X in ZZ and 4 <= X <= 37)): raise ValueError(error_msg % X) # transforming two reducible types and an irreducible type if isinstance(X, CartanType_abstract): if not X.is_finite(): raise ValueError(error_msg % X) if hasattr(X, "cartan_type"): X = X.cartan_type() if X.is_irreducible(): W_types.extend([(X.letter, X.n)]) else: W_types.extend([(x.letter, x.n) for x in X.component_types()]) elif X == (2, 2, 2) or X == ("I", 2): W_types.extend([("A", 1), ("A", 1)]) elif X == (2, 2, 3): W_types.extend([("A", 3)]) else: W_types.append(X) # converting the real types given as complex types # and then checking for real vs complex for i, W_type in enumerate(W_types): if W_type in ZZ: if W_type == 23: W_types[i] = ("H", 3) elif W_type == 28: W_types[i] = ("F", 4) elif W_type == 30: W_types[i] = ("H", 4) elif W_type == 35: W_types[i] = ("E", 6) elif W_type == 36: W_types[i] = ("E", 7) elif W_type == 37: W_types[i] = ("E", 8) if isinstance(W_type, tuple) and len(W_type) == 3: if W_type[0] == W_type[1] == 1: W_types[i] = ("A", W_type[2] - 1) elif W_type[0] == 2 and W_type[1] == 1: W_types[i] = ("B", W_type[2]) elif W_type[0] == W_type[1] == 2: W_types[i] = ("D", W_type[2]) elif W_type[0] == W_type[1] and W_type[2] == 2: W_types[i] = ("I", W_type[0]) W_type = W_types[i] # check for real vs complex if W_type in ZZ or (isinstance(W_type, tuple) and len(W_type) == 3): is_complex = True for index_set_kwd in ["index_set", "hyperplane_index_set", "reflection_index_set"]: index_set = kwds.get(index_set_kwd, None) if index_set is not None: if isinstance(index_set, (list, tuple)): kwds[index_set_kwd] = tuple(index_set) else: raise ValueError("the keyword %s must be a list or tuple" % index_set_kwd) if len(W_types) == 1: if is_complex is True: cls = IrreducibleComplexReflectionGroup else: cls = IrreducibleRealReflectionGroup else: if is_complex is True: cls = ComplexReflectionGroup else: cls = RealReflectionGroup return cls( tuple(W_types), index_set=kwds.get("index_set", None), hyperplane_index_set=kwds.get("hyperplane_index_set", None), reflection_index_set=kwds.get("reflection_index_set", None), )
def ReflectionGroup(*args,**kwds): r""" Construct a finite (complex or real) reflection group as a Sage permutation group by fetching the permutation representation of the generators from chevie's database. INPUT: can be one or multiple of the following: - a triple `(r, p, n)` with `p` divides `r`, which denotes the group `G(r, p, n)` - an integer between `4` and `37`, which denotes an exceptional irreducible complex reflection group - a finite Cartan-Killing type EXAMPLES: Finite reflection groups can be constructed from Cartan-Killing classification types:: sage: W = ReflectionGroup(['A',3]); W # optional - gap3 Irreducible real reflection group of rank 3 and type A3 sage: W = ReflectionGroup(['H',4]); W # optional - gap3 Irreducible real reflection group of rank 4 and type H4 sage: W = ReflectionGroup(['I',5]); W # optional - gap3 Irreducible real reflection group of rank 2 and type I2(5) the complex infinite family `G(r,p,n)` with `p` divides `r`:: sage: W = ReflectionGroup((1,1,4)); W # optional - gap3 Irreducible real reflection group of rank 3 and type A3 sage: W = ReflectionGroup((2,1,3)); W # optional - gap3 Irreducible real reflection group of rank 3 and type B3 Chevalley-Shepard-Todd exceptional classification types:: sage: W = ReflectionGroup(23); W # optional - gap3 Irreducible real reflection group of rank 3 and type H3 Cartan types and matrices:: sage: ReflectionGroup(CartanType(['A',2])) # optional - gap3 Irreducible real reflection group of rank 2 and type A2 sage: ReflectionGroup(CartanType((['A',2],['A',2]))) # optional - gap3 Reducible real reflection group of rank 4 and type A2 x A2 sage: C = CartanMatrix(['A',2]) # optional - gap3 sage: ReflectionGroup(C) # optional - gap3 Irreducible real reflection group of rank 2 and type A2 multiples of the above:: sage: W = ReflectionGroup(['A',2],['B',2]); W # optional - gap3 Reducible real reflection group of rank 4 and type A2 x B2 sage: W = ReflectionGroup(['A',2],4); W # optional - gap3 Reducible complex reflection group of rank 4 and type A2 x ST4 sage: W = ReflectionGroup((4,2,2),4); W # optional - gap3 Reducible complex reflection group of rank 4 and type G(4,2,2) x ST4 """ if not is_chevie_available(): raise ImportError("the GAP3 package 'chevie' is needed to work with (complex) reflection groups") gap3.load_package("chevie") error_msg = "the input data (%s) is not valid for reflection groups" W_types = [] is_complex = False for arg in args: # preparsing if isinstance(arg, list): X = tuple(arg) else: X = arg # precheck for valid input data if not (isinstance(X, (CartanType_abstract,tuple)) or (X in ZZ and 4 <= X <= 37)): raise ValueError(error_msg%X) # transforming two reducible types and an irreducible type if isinstance(X, CartanType_abstract): if not X.is_finite(): raise ValueError(error_msg%X) if hasattr(X,"cartan_type"): X = X.cartan_type() if X.is_irreducible(): W_types.extend([(X.letter, X.n)]) else: W_types.extend([(x.letter, x.n) for x in X.component_types()]) elif X == (2,2,2) or X == ('I',2): W_types.extend([('A',1), ('A',1)]) elif X == (2,2,3): W_types.extend([('A', 3)]) else: W_types.append(X) # converting the real types given as complex types # and then checking for real vs complex for i,W_type in enumerate(W_types): if W_type in ZZ: if W_type == 23: W_types[i] = ('H', 3) elif W_type == 28: W_types[i] = ('F', 4) elif W_type == 30: W_types[i] = ('H', 4) elif W_type == 35: W_types[i] = ('E', 6) elif W_type == 36: W_types[i] = ('E', 7) elif W_type == 37: W_types[i] = ('E', 8) if isinstance(W_type,tuple) and len(W_type) == 3: if W_type[0] == W_type[1] == 1: W_types[i] = ('A', W_type[2]-1) elif W_type[0] == 2 and W_type[1] == 1: W_types[i] = ('B', W_type[2]) elif W_type[0] == W_type[1] == 2: W_types[i] = ('D', W_type[2]) elif W_type[0] == W_type[1] and W_type[2] == 2: W_types[i] = ('I', W_type[0]) W_type = W_types[i] # check for real vs complex if W_type in ZZ or (isinstance(W_type, tuple) and len(W_type) == 3): is_complex = True for index_set_kwd in ['index_set', 'hyperplane_index_set', 'reflection_index_set']: index_set = kwds.get(index_set_kwd, None) if index_set is not None: if isinstance(index_set, (list, tuple)): kwds[index_set_kwd] = tuple(index_set) else: raise ValueError('the keyword %s must be a list or tuple'%index_set_kwd) if len(W_types) == 1: if is_complex is True: cls = IrreducibleComplexReflectionGroup else: cls = IrreducibleRealReflectionGroup else: if is_complex is True: cls = ComplexReflectionGroup else: cls = RealReflectionGroup return cls(tuple(W_types), index_set=kwds.get('index_set', None), hyperplane_index_set=kwds.get('hyperplane_index_set', None), reflection_index_set=kwds.get('reflection_index_set', None))