def _from_matrix(cls, data, coxeter_type, index_set, coxeter_type_check): """ Initiate the Coxeter matrix from a matrix. TESTS:: sage: CM = CoxeterMatrix([[1,2],[2,1]]); CM [1 2] [2 1] sage: CM = CoxeterMatrix([[1,-1],[-1,1]]); CM [ 1 -1] [-1 1] sage: CM = CoxeterMatrix([[1,-1.5],[-1.5,1]]); CM [ 1.00000000000000 -1.50000000000000] [-1.50000000000000 1.00000000000000] sage: CM = CoxeterMatrix([[1,-3/2],[-3/2,1]]); CM [ 1 -3/2] [-3/2 1] sage: CM = CoxeterMatrix([[1,-3/2,5],[-3/2,1,-1],[5,-1,1]]); CM [ 1 -3/2 5] [-3/2 1 -1] [ 5 -1 1] sage: CM = CoxeterMatrix([[1,-3/2,5],[-3/2,1,oo],[5,oo,1]]); CM [ 1 -3/2 5] [-3/2 1 -1] [ 5 -1 1] """ # Check that the data is valid check_coxeter_matrix(data) M = matrix(data) n = M.ncols() base_ring = M.base_ring() if not coxeter_type: if n == 1: coxeter_type = CoxeterType(['A', 1]) elif coxeter_type_check: coxeter_type = recognize_coxeter_type_from_matrix(M, index_set) else: coxeter_type = None raw_data = M.list() mat = typecall(cls, MatrixSpace(base_ring, n, sparse=False), raw_data, coxeter_type, index_set) mat._subdivisions = M._subdivisions return mat
def __classcall__(cls, *args, **options): """ Constructs a new object of this class or reuse an existing one. See also :class:`UniqueRepresentation` for a discussion. EXAMPLES:: sage: x = UniqueRepresentation() sage: y = UniqueRepresentation() sage: x is y True """ instance = typecall(cls, *args, **options) assert isinstance( instance, cls ) if instance.__class__.__reduce__ == UniqueRepresentation.__reduce__: instance._reduction = (cls, args, options) return instance
def __classcall_private__(cls, dynamical_system, domain=None): """ Return the approapriate dynamical system on projective Berkovich space over ``Cp``. EXAMPLES:: sage: P1.<x,y> = ProjectiveSpace(Qp(3), 1) sage: from sage.dynamics.arithmetic_dynamics.berkovich_ds import DynamicalSystem_Berkovich_projective sage: DynamicalSystem_Berkovich_projective([y, x]) Dynamical system of Projective Berkovich line over Cp(3) of precision 20 induced by the map Defn: Defined on coordinates by sending (x : y) to (y : x) """ if not isinstance(dynamical_system, DynamicalSystem): if not isinstance(dynamical_system, DynamicalSystem_projective): dynamical_system = DynamicalSystem_projective(dynamical_system) else: raise TypeError( 'affine dynamical system passed to projective constructor') R = dynamical_system.base_ring() morphism_domain = dynamical_system.domain() if not is_ProjectiveSpace(morphism_domain): raise TypeError( 'the domain of dynamical_system must be projective space, not %s' % morphism_domain) if morphism_domain.dimension_relative() != 1: raise ValueError('domain was not relative dimension 1') if not isinstance(R, pAdicBaseGeneric): if domain is None: raise TypeError('dynamical system defined over %s, not p-adic, ' %morphism_domain.base_ring() + \ 'and domain is None') if not isinstance(domain, Berkovich_Cp_Projective): raise TypeError( 'domain was %s, not a projective Berkovich space over Cp' % domain) if domain.base() != morphism_domain: raise ValueError('base of domain was %s, with coordinate ring %s ' %(domain.base(), \ domain.base().coordinate_ring())+ 'while dynamical_system acts on %s, ' %morphism_domain + \ 'with coordinate ring %s' %morphism_domain.coordinate_ring()) else: domain = Berkovich_Cp_Projective(morphism_domain) return typecall(cls, dynamical_system, domain)
def factory(self, module, grading): if module._yacop_grading is grading: return module # this code is modelled on the unpickling of unique representation objects: # we create a clone of the module which we can modify, and we also # refine the class to SuspendedObjects if that has been requested cls, args, options = module._reduction if not hasattr(cls, self._functor_category): # create a dummy SuspendedObjects class - is this a good idea? # setattr(cls, self._functor_category,cls) pass else: cls = getattr(cls, self._functor_category) from copy import copy dct = copy(options) dct["category"] = module.category().SuspendedObjects() N = typecall(cls, *args, **dct) # set the grading and the new name N._yacop_grading = grading N._yacop_ref = module N.rename(grading._format_(module)) # a couple of hacks follow: # - fix variable injection if hasattr(N, "gens"): def gens(): return module.gens() setattr(N, "gens", gens) if hasattr(N, "variables"): def variables(): return module.variables() setattr(N, "variables", variables) return N
def __classcall_private__(cls, dynamical_system, domain=None): """ Return the appropriate dynamical system on affine Berkovich space over ``Cp``. EXAMPLES:: sage: A.<x> = AffineSpace(Qp(3), 1) sage: from sage.dynamics.arithmetic_dynamics.berkovich_ds import DynamicalSystem_Berkovich_affine sage: DynamicalSystem_Berkovich_affine(DynamicalSystem_affine(x^2)) Dynamical system of Affine Berkovich line over Cp(3) of precision 20 induced by the map Defn: Defined on coordinates by sending (x) to (x^2) """ if not isinstance(dynamical_system, DynamicalSystem): if not isinstance(dynamical_system, DynamicalSystem_affine): dynamical_system = DynamicalSystem_projective(dynamical_system) else: raise TypeError( 'projective dynamical system passed to affine constructor') R = dynamical_system.base_ring() morphism_domain = dynamical_system.domain() if not is_AffineSpace(morphism_domain): raise TypeError( 'the domain of dynamical_system must be affine space, not %s' % morphism_domain) if morphism_domain.dimension_relative() != 1: raise ValueError('domain not relative dimension 1') if not isinstance(R, pAdicBaseGeneric): if domain is None: raise TypeError('dynamical system defined over %s, not padic, ' %morphism_domain.base_ring() + \ 'and domain was not specified') if not isinstance(domain, Berkovich_Cp_Affine): raise TypeError( 'domain was %s, not an affine Berkovich space over Cp' % domain) else: domain = Berkovich_Cp_Affine(morphism_domain.base_ring()) return typecall(cls, dynamical_system, domain)
def __classcall_private__(cls, data=None, index_set=None, coxeter_type=None, cartan_type=None, coxeter_type_check=True): r""" A Coxeter matrix can we created via a graph, a Coxeter type, or a matrix. .. NOTE:: To disable the Coxeter type check, use the optional argument ``coxeter_type_check = False``. EXAMPLES:: sage: C = CoxeterMatrix(['A',1,1],['a','b']) sage: C2 = CoxeterMatrix([[1, -1], [-1, 1]]) sage: C3 = CoxeterMatrix(matrix([[1, -1], [-1, 1]]), [0, 1]) sage: C == C2 and C == C3 True Check with `\infty` because of the hack of using `-1` to represent `\infty` in the Coxeter matrix:: sage: G = Graph([(0, 1, 3), (1, 2, oo)]) sage: W1 = CoxeterMatrix([[1, 3, 2], [3, 1, -1], [2, -1, 1]]) sage: W2 = CoxeterMatrix(G) sage: W1 == W2 True sage: CoxeterMatrix(W1.coxeter_graph()) == W1 True The base ring of the matrix depends on the entries given:: sage: CoxeterMatrix([[1,-1],[-1,1]])._matrix.base_ring() Integer Ring sage: CoxeterMatrix([[1,-3/2],[-3/2,1]])._matrix.base_ring() Rational Field sage: CoxeterMatrix([[1,-1.5],[-1.5,1]])._matrix.base_ring() Real Field with 53 bits of precision """ if not data: if coxeter_type: data = CoxeterType(coxeter_type) elif cartan_type: data = CoxeterType(CartanType(cartan_type)) # Special cases with no arguments passed if not data: data = [] n = 0 index_set = tuple() coxeter_type = None base_ring = ZZ mat = typecall(cls, MatrixSpace(base_ring, n, sparse=False), data, coxeter_type, index_set) mat._subdivisions = None return mat if isinstance(data, CoxeterMatrix): # Initiate from itself return data # Initiate from a graph: # TODO: Check if a CoxeterDiagram once implemented if isinstance(data, Graph): return cls._from_graph(data, coxeter_type_check) # Get the Coxeter type coxeter_type = None from sage.combinat.root_system.cartan_type import CartanType_abstract if isinstance(data, CartanType_abstract): coxeter_type = data.coxeter_type() else: try: coxeter_type = CoxeterType(data) except (TypeError, ValueError, NotImplementedError): pass # Initiate from a Coxeter type if coxeter_type: return cls._from_coxetertype(coxeter_type) # TODO:: remove when oo is possible in matrices. n = len(data[0]) data = [x if x != infinity else -1 for r in data for x in r] data = matrix(n, n, data) # until here # Get the index set if index_set: index_set = tuple(index_set) else: index_set = tuple(range(1, n + 1)) if len(set(index_set)) != n: raise ValueError("the given index set is not valid") return cls._from_matrix(data, coxeter_type, index_set, coxeter_type_check)
def __classcall_private__(cls, *args, **kwds): """ Normalize input so we can inherit from spare integer matrix. .. NOTE:: To disable the Cartan type check, use the optional argument ``cartan_type_check = False``. EXAMPLES:: sage: C = CartanMatrix(['A',1,1]) sage: C2 = CartanMatrix([[2, -2], [-2, 2]]) sage: C3 = CartanMatrix(matrix([[2, -2], [-2, 2]]), [0, 1]) sage: C == C2 and C == C3 True TESTS: Check that :trac:`15740` is fixed:: sage: d = DynkinDiagram() sage: d.add_edge('a', 'b', 2) sage: d.index_set() ('a', 'b') sage: cm = CartanMatrix(d) sage: cm.index_set() ('a', 'b') """ # Special case with 0 args and kwds has Cartan type if "cartan_type" in kwds and len(args) == 0: args = (CartanType(kwds["cartan_type"]),) if len(args) == 0: data = [] n = 0 index_set = tuple() cartan_type = None subdivisions = None elif len(args) == 4 and isinstance(args[0], MatrixSpace): # For pickling return typecall(cls, args[0], args[1], args[2], args[3]) elif isinstance(args[0], CartanMatrix): return args[0] else: cartan_type = None dynkin_diagram = None subdivisions = None from sage.combinat.root_system.dynkin_diagram import DynkinDiagram_class if isinstance(args[0], DynkinDiagram_class): dynkin_diagram = args[0] cartan_type = args[0]._cartan_type else: try: cartan_type = CartanType(args[0]) dynkin_diagram = cartan_type.dynkin_diagram() except (TypeError, ValueError): pass if dynkin_diagram is not None: n = dynkin_diagram.rank() index_set = dynkin_diagram.index_set() reverse = dict((index_set[i], i) for i in range(len(index_set))) data = {(i, i): 2 for i in range(n)} for (i,j,l) in dynkin_diagram.edge_iterator(): data[(reverse[j], reverse[i])] = -l else: M = matrix(args[0]) if not is_generalized_cartan_matrix(M): raise ValueError("the input matrix is not a generalized Cartan matrix") n = M.ncols() if "cartan_type" in kwds: cartan_type = CartanType(kwds["cartan_type"]) elif n == 1: cartan_type = CartanType(['A', 1]) elif kwds.get("cartan_type_check", True): cartan_type = find_cartan_type_from_matrix(M) data = M.dict() subdivisions = M._subdivisions if len(args) == 1: if cartan_type is not None: index_set = tuple(cartan_type.index_set()) elif dynkin_diagram is None: index_set = tuple(range(n)) elif len(args) == 2: index_set = tuple(args[1]) if len(index_set) != n and len(set(index_set)) != n: raise ValueError("the given index set is not valid") else: raise ValueError("too many arguments") mat = typecall(cls, MatrixSpace(ZZ, n, sparse=True), data, cartan_type, index_set) mat._subdivisions = subdivisions return mat
def __classcall_private__( cls, data=None, index_set=None, coxeter_type=None, cartan_type=None, coxeter_type_check=True ): r""" A Coxeter matrix can we created via a graph, a Coxeter type, or a matrix. .. NOTE:: To disable the Coxeter type check, use the optional argument ``coxeter_type_check = False``. EXAMPLES:: sage: C = CoxeterMatrix(['A',1,1],['a','b']) sage: C2 = CoxeterMatrix([[1, -1], [-1, 1]]) sage: C3 = CoxeterMatrix(matrix([[1, -1], [-1, 1]]), [0, 1]) sage: C == C2 and C == C3 True Check with `\infty` because of the hack of using `-1` to represent `\infty` in the Coxeter matrix:: sage: G = Graph([(0, 1, 3), (1, 2, oo)]) sage: W1 = CoxeterMatrix([[1, 3, 2], [3, 1, -1], [2, -1, 1]]) sage: W2 = CoxeterMatrix(G) sage: W1 == W2 True sage: CoxeterMatrix(W1.coxeter_graph()) == W1 True The base ring of the matrix depends on the entries given:: sage: CoxeterMatrix([[1,-1],[-1,1]])._matrix.base_ring() Integer Ring sage: CoxeterMatrix([[1,-3/2],[-3/2,1]])._matrix.base_ring() Rational Field sage: CoxeterMatrix([[1,-1.5],[-1.5,1]])._matrix.base_ring() Real Field with 53 bits of precision """ if not data: if coxeter_type: data = CoxeterType(coxeter_type) elif cartan_type: data = CoxeterType(CartanType(cartan_type)) # Special cases with no arguments passed if not data: data = [] n = 0 index_set = tuple() coxeter_type = None base_ring = ZZ mat = typecall(cls, MatrixSpace(base_ring, n, sparse=False), data, coxeter_type, index_set) mat._subdivisions = None return mat if isinstance(data, CoxeterMatrix): # Initiate from itself return data # Initiate from a graph: # TODO: Check if a CoxeterDiagram once implemented if isinstance(data, Graph): return cls._from_graph(data, coxeter_type_check) # Get the Coxeter type coxeter_type = None from sage.combinat.root_system.cartan_type import CartanType_abstract if isinstance(data, CartanType_abstract): coxeter_type = data.coxeter_type() else: try: coxeter_type = CoxeterType(data) except (TypeError, ValueError, NotImplementedError): pass # Initiate from a Coxeter type if coxeter_type: return cls._from_coxetertype(coxeter_type) # TODO:: remove when oo is possible in matrices. n = len(data[0]) data = [x if x != infinity else -1 for r in data for x in r] data = matrix(n, n, data) # until here # Get the index set if index_set: index_set = tuple(index_set) else: index_set = tuple(range(1, n + 1)) if len(set(index_set)) != n: raise ValueError("the given index set is not valid") return cls._from_matrix(data, coxeter_type, index_set, coxeter_type_check)
def __classcall_private__(cls, X, phi, cache_orbits=False, create_tuple=False, inverse=None, is_finite=None): """ Return the correct object based on input. The main purpose of this method is to decide which subclass the object will belong to based on the ``inverse`` and ``is_finite`` arguments. EXAMPLES:: sage: D = DiscreteDynamicalSystem(NN, lambda x: x + 1) sage: parent(D) <class 'sage.dynamics.finite_dynamical_system.DiscreteDynamicalSystem'> sage: f1 = lambda x: (x + 2 if x % 6 < 4 else x - 4) sage: D = DiscreteDynamicalSystem(NN, f1, inverse=False) sage: parent(D) <class 'sage.dynamics.finite_dynamical_system.DiscreteDynamicalSystem'> sage: D = DiscreteDynamicalSystem(NN, f1, inverse=None) sage: parent(D) <class 'sage.dynamics.finite_dynamical_system.DiscreteDynamicalSystem'> sage: D = DiscreteDynamicalSystem(NN, f1, inverse=True) sage: parent(D) <class 'sage.dynamics.finite_dynamical_system.InvertibleDiscreteDynamicalSystem'> sage: D = DiscreteDynamicalSystem(NN, lambda x: x + 1, is_finite=False) sage: parent(D) <class 'sage.dynamics.finite_dynamical_system.DiscreteDynamicalSystem'> sage: f2 = lambda x: (x + 1 if x < 3 else 1) sage: f3 = lambda x: (x - 1 if x > 3 else 3) sage: D = DiscreteDynamicalSystem([1, 2, 3], f2) sage: parent(D) <class 'sage.dynamics.finite_dynamical_system.FiniteDynamicalSystem'> sage: D = DiscreteDynamicalSystem([1, 2, 3], f2, inverse=True) sage: parent(D) <class 'sage.dynamics.finite_dynamical_system.InvertibleFiniteDynamicalSystem'> sage: D = DiscreteDynamicalSystem([1, 2, 3], f2, inverse=f3) sage: parent(D) <class 'sage.dynamics.finite_dynamical_system.InvertibleFiniteDynamicalSystem'> sage: D = DiscreteDynamicalSystem([1, 2, 3], f2, inverse=False) sage: parent(D) <class 'sage.dynamics.finite_dynamical_system.FiniteDynamicalSystem'> sage: D = DiscreteDynamicalSystem([1, 2, 3], f2, inverse=None) sage: parent(D) <class 'sage.dynamics.finite_dynamical_system.FiniteDynamicalSystem'> """ if is_finite is None: is_finite = (X in Sets().Finite() or isinstance(X, (list, tuple, set, frozenset))) if inverse: if inverse is True: # invertibility claimed, but inverse not provided # This is how the input for these subclasses work inverse = None ret_cls = (InvertibleFiniteDynamicalSystem if is_finite else InvertibleDiscreteDynamicalSystem) return ret_cls(X, phi, cache_orbits=cache_orbits, create_tuple=create_tuple, inverse=inverse) if is_finite: return FiniteDynamicalSystem(X, phi, cache_orbits=cache_orbits, create_tuple=create_tuple) return typecall(cls, X, phi, cache_orbits=cache_orbits, create_tuple=create_tuple)
def __classcall__(cls, id=None, **kwds): r""" Construct a new texture by id. INPUT: - ``id`` - a texture (optional, default: None), a dict, a color, a str, a tuple, None or any other type acting as an ID. If ``id`` is None and keyword ``texture`` is empty, then it returns a unique texture object. - ``texture`` - a texture - ``color`` - tuple or str, (optional, default: (.4, .4, 1)) - ``opacity`` - number between 0 and 1 (optional, default: 1) - ``ambient`` - number (optional, default: 0.5) - ``diffuse`` - number (optional, default: 1) - ``specular`` - number (optional, default: 0) - ``shininess`` - number (optional, default: 1) - ``name`` - str (optional, default: None) - ``**kwds`` - other valid keywords OUTPUT: A texture object. EXAMPLES: Texture from integer ``id``:: sage: from sage.plot.plot3d.texture import Texture sage: Texture(17) Texture(17, 6666ff) Texture from rational ``id``:: sage: Texture(3/4) Texture(3/4, 6666ff) Texture from a dict:: sage: Texture({'color':'orange','opacity':0.5}) Texture(texture..., orange, ffa500) Texture from a color:: sage: c = Color('red') sage: Texture(c) Texture(texture..., ff0000) Texture from a valid string color:: sage: Texture('red') Texture(texture..., red, ff0000) Texture from a non valid string color:: sage: Texture('redd') Texture(redd, 6666ff) Texture from a tuple:: sage: Texture((.2,.3,.4)) Texture(texture..., 334c66) Now accepting negative arguments, reduced modulo 1:: sage: Texture((-3/8, 1/2, 3/8)) Texture(texture..., 9f7f5f) Textures using other keywords:: sage: Texture(specular=0.4) Texture(texture..., 6666ff) sage: Texture(diffuse=0.4) Texture(texture..., 6666ff) sage: Texture(shininess=0.3) Texture(texture..., 6666ff) sage: Texture(ambient=0.7) Texture(texture..., 6666ff) """ if isinstance(id, Texture): return id if 'texture' in kwds: t = kwds['texture'] if isinstance(t, Texture): return t else: raise TypeError("texture keyword must be a texture object") if isinstance(id, dict): kwds = id if 'rgbcolor' in kwds: kwds['color'] = kwds['rgbcolor'] id = None elif isinstance(id, Color): kwds['color'] = id.rgb() id = None elif isinstance(id, str) and id in colors: kwds['color'] = id id = None elif isinstance(id, tuple): kwds['color'] = id id = None if id is None: id = _new_global_texture_id() return typecall(cls, id, **kwds)
def __classcall_private__(cls, *args, **kwds): """ Normalize input so we can inherit from spare integer matrix. .. NOTE:: To disable the Cartan type check, use the optional argument ``cartan_type_check = False``. EXAMPLES:: sage: C = CartanMatrix(['A',1,1]) sage: C2 = CartanMatrix([[2, -2], [-2, 2]]) sage: C3 = CartanMatrix(matrix([[2, -2], [-2, 2]]), [0, 1]) sage: C == C2 and C == C3 True """ # Special case with 0 args and kwds has cartan type if "cartan_type" in kwds and len(args) == 0: args = (CartanType(kwds["cartan_type"]),) if len(args) == 0: data = [] n = 0 index_set = tuple() cartan_type = None subdivisions = None elif len(args) == 4 and isinstance(args[0], MatrixSpace): # For pickling return typecall(cls, args[0], args[1], args[2], args[3]) elif isinstance(args[0], CartanMatrix): return args[0] else: cartan_type = None dynkin_diagram = None subdivisions = None try: cartan_type = CartanType(args[0]) dynkin_diagram = cartan_type.dynkin_diagram() except (TypeError, ValueError): pass if dynkin_diagram is not None: n = cartan_type.rank() index_set = dynkin_diagram.index_set() reverse = dict((index_set[i], i) for i in range(len(index_set))) data = {(i, i): 2 for i in range(n)} for (i,j,l) in dynkin_diagram.edge_iterator(): data[(reverse[j], reverse[i])] = -l else: M = matrix(args[0]) if not is_generalized_cartan_matrix(M): raise ValueError("The input matrix is not a generalized Cartan matrix.") n = M.ncols() if "cartan_type" in kwds: cartan_type = CartanType(kwds["cartan_type"]) elif n == 1: cartan_type = CartanType(['A', 1]) elif kwds.get("cartan_type_check", True): cartan_type = find_cartan_type_from_matrix(M) data = M.dict() subdivisions = M._subdivisions if len(args) == 1: if cartan_type is not None: index_set = tuple(cartan_type.index_set()) else: index_set = tuple(range(M.ncols())) elif len(args) == 2: index_set = tuple(args[1]) if len(index_set) != n and len(set(index_set)) != n: raise ValueError("The given index set is not valid.") else: raise ValueError("Too many arguments.") mat = typecall(cls, MatrixSpace(ZZ, n, sparse=True), data, cartan_type, index_set) mat._subdivisions = subdivisions return mat
def __classcall_private__(cls, morphism_or_polys, domain=None): r""" Return the appropriate dynamical system on an affine scheme. TESTS:: sage: A.<x> = AffineSpace(ZZ,1) sage: A1.<z> = AffineSpace(CC,1) sage: H = End(A1) sage: f2 = H([z^2+1]) sage: f = DynamicalSystem_affine(f2, A) sage: f.domain() is A False :: sage: P1.<x,y> = ProjectiveSpace(QQ,1) sage: DynamicalSystem_affine([y, 2*x], domain=P1) Traceback (most recent call last): ... ValueError: "domain" must be an affine scheme sage: H = End(P1) sage: DynamicalSystem_affine(H([y, 2*x])) Traceback (most recent call last): ... ValueError: "domain" must be an affine scheme """ if isinstance(morphism_or_polys, SchemeMorphism_polynomial): morphism = morphism_or_polys R = morphism.base_ring() polys = list(morphism) domain = morphism.domain() if not is_AffineSpace(domain) and not isinstance( domain, AlgebraicScheme_subscheme_affine): raise ValueError('"domain" must be an affine scheme') if domain != morphism_or_polys.codomain(): raise ValueError('domain and codomain do not agree') if R not in Fields(): return typecall(cls, polys, domain) if is_FiniteField(R): return DynamicalSystem_affine_finite_field(polys, domain) return DynamicalSystem_affine_field(polys, domain) elif isinstance(morphism_or_polys, (list, tuple)): polys = list(morphism_or_polys) else: polys = [morphism_or_polys] # We now arrange for all of our list entries to lie in the same ring # Fraction field case first fraction_field = False for poly in polys: P = poly.parent() if is_FractionField(P): fraction_field = True break if fraction_field: K = P.base_ring().fraction_field() # Replace base ring with its fraction field P = P.ring().change_ring(K).fraction_field() polys = [P(poly) for poly in polys] else: # If any of the list entries lies in a quotient ring, we try # to lift all entries to a common polynomial ring. quotient_ring = False for poly in polys: P = poly.parent() if is_QuotientRing(P): quotient_ring = True break if quotient_ring: polys = [P(poly).lift() for poly in polys] else: poly_ring = False for poly in polys: P = poly.parent() if is_PolynomialRing(P) or is_MPolynomialRing(P): poly_ring = True break if poly_ring: polys = [P(poly) for poly in polys] if domain is None: f = polys[0] CR = f.parent() if CR is SR: raise TypeError("Symbolic Ring cannot be the base ring") if fraction_field: CR = CR.ring() domain = AffineSpace(CR) R = domain.base_ring() if R is SR: raise TypeError("Symbolic Ring cannot be the base ring") if not is_AffineSpace(domain) and not isinstance( domain, AlgebraicScheme_subscheme_affine): raise ValueError('"domain" must be an affine scheme') if R not in Fields(): return typecall(cls, polys, domain) if is_FiniteField(R): return DynamicalSystem_affine_finite_field(polys, domain) return DynamicalSystem_affine_field(polys, domain)
def __classcall_private__(cls, data=None, index_set=None, cartan_type=None, cartan_type_check=True, borcherds=None): """ Normalize input so we can inherit from sparse integer matrix. .. NOTE:: To disable the Cartan type check, use the optional argument ``cartan_type_check = False``. EXAMPLES:: sage: C = CartanMatrix(['A',1,1]) sage: C2 = CartanMatrix([[2, -2], [-2, 2]]) sage: C3 = CartanMatrix(matrix([[2, -2], [-2, 2]]), [0, 1]) sage: C == C2 and C == C3 True TESTS: Check that :trac:`15740` is fixed:: sage: d = DynkinDiagram() sage: d.add_edge('a', 'b', 2) sage: d.index_set() ('a', 'b') sage: cm = CartanMatrix(d) sage: cm.index_set() ('a', 'b') """ # Special case with 0 args and kwds has Cartan type if cartan_type is not None and data is None: data = CartanType(cartan_type) if data is None: data = [] n = 0 index_set = tuple() cartan_type = None subdivisions = None elif isinstance(data, CartanMatrix): if index_set is not None: d = {a: index_set[i] for i,a in enumerate(data.index_set())} return data.relabel(d) return data else: dynkin_diagram = None subdivisions = None from sage.combinat.root_system.dynkin_diagram import DynkinDiagram_class if isinstance(data, DynkinDiagram_class): dynkin_diagram = data cartan_type = data._cartan_type else: try: cartan_type = CartanType(data) dynkin_diagram = cartan_type.dynkin_diagram() except (TypeError, ValueError): pass if dynkin_diagram is not None: n = dynkin_diagram.rank() index_set = dynkin_diagram.index_set() oir = dynkin_diagram.odd_isotropic_roots() reverse = {a: i for i,a in enumerate(index_set)} if isinstance(borcherds, (list, tuple)): if (len(borcherds) != len(index_set) and not all(val in ZZ and (val == 2 or (val % 2 == 0 and val < 0)) for val in borcherds)): raise ValueError("the input data is not a Borcherds-Cartan matrix") data = {(i, i): val if index_set[i] not in oir else 0 for i,val in enumerate(borcherds)} else: data = {(i, i): 2 if index_set[i] not in oir else 0 for i in range(n)} for (i,j,l) in dynkin_diagram.edge_iterator(): data[(reverse[j], reverse[i])] = -l else: M = matrix(data) if borcherds: if not is_borcherds_cartan_matrix(M): raise ValueError("the input matrix is not a Borcherds-Cartan matrix") else: if not is_generalized_cartan_matrix(M): raise ValueError("the input matrix is not a generalized Cartan matrix") n = M.ncols() data = M.dict() subdivisions = M._subdivisions if index_set is None: index_set = tuple(range(n)) else: index_set = tuple(index_set) if len(index_set) != n and len(set(index_set)) != n: raise ValueError("the given index set is not valid") # We can do the Cartan type initialization later as this is not # a unique representation mat = typecall(cls, MatrixSpace(ZZ, n, sparse=True), data, False, True) # FIXME: We have to initialize the CartanMatrix part separately because # of the __cinit__ of the matrix. We should get rid of this workaround mat._CM_init(cartan_type, index_set, cartan_type_check) mat._subdivisions = subdivisions return mat
def __classcall_private__(cls, morphism_or_polys, domain=None): r""" Return the appropriate dynamical system on an affine scheme. TESTS:: sage: A.<x> = AffineSpace(ZZ,1) sage: A1.<z> = AffineSpace(CC,1) sage: H = End(A1) sage: f2 = H([z^2+1]) sage: f = DynamicalSystem_affine(f2, A) sage: f.domain() is A False :: sage: P1.<x,y> = ProjectiveSpace(QQ,1) sage: DynamicalSystem_affine([y, 2*x], domain=P1) Traceback (most recent call last): ... ValueError: "domain" must be an affine scheme sage: H = End(P1) sage: DynamicalSystem_affine(H([y, 2*x])) Traceback (most recent call last): ... ValueError: "domain" must be an affine scheme :: sage: R.<x,y,z> = QQ[] sage: f = DynamicalSystem_affine([x+y+z, y*z]) Traceback (most recent call last): ... ValueError: Number of polys does not match dimension of Affine Space of dimension 3 over Rational Field :: sage: A.<x,y> = AffineSpace(QQ,2) sage: f = DynamicalSystem_affine([CC.0*x^2, y^2], domain=A) Traceback (most recent call last): ... TypeError: coefficients of polynomial not in Rational Field """ if isinstance(morphism_or_polys, SchemeMorphism_polynomial): morphism = morphism_or_polys R = morphism.base_ring() polys = list(morphism) domain = morphism.domain() if not is_AffineSpace(domain) and not isinstance(domain, AlgebraicScheme_subscheme_affine): raise ValueError('"domain" must be an affine scheme') if domain != morphism_or_polys.codomain(): raise ValueError('domain and codomain do not agree') if R not in Fields(): return typecall(cls, polys, domain) if is_FiniteField(R): return DynamicalSystem_affine_finite_field(polys, domain) return DynamicalSystem_affine_field(polys, domain) elif isinstance(morphism_or_polys,(list, tuple)): polys = list(morphism_or_polys) else: polys = [morphism_or_polys] PR = get_coercion_model().common_parent(*polys) fraction_field = any(is_FractionField(poly.parent()) for poly in polys) if fraction_field: K = PR.base_ring().fraction_field() # Replace base ring with its fraction field PR = PR.ring().change_ring(K).fraction_field() polys = [PR(poly) for poly in polys] else: quotient_ring = any(is_QuotientRing(poly.parent()) for poly in polys) # If any of the list entries lies in a quotient ring, we try # to lift all entries to a common polynomial ring. if quotient_ring: polys = [PR(poly).lift() for poly in polys] else: polys = [PR(poly) for poly in polys] if domain is None: if PR is SR: raise TypeError("Symbolic Ring cannot be the base ring") if fraction_field: PR = PR.ring() domain = AffineSpace(PR) else: # Check if we can coerce the given polynomials over the given domain PR = domain.ambient_space().coordinate_ring() try: if fraction_field: PR = PR.fraction_field() polys = [PR(poly) for poly in polys] except TypeError: raise TypeError('coefficients of polynomial not in {}'.format(domain.base_ring())) if len(polys) != domain.ambient_space().coordinate_ring().ngens(): raise ValueError('Number of polys does not match dimension of {}'.format(domain)) R = domain.base_ring() if R is SR: raise TypeError("Symbolic Ring cannot be the base ring") if not is_AffineSpace(domain) and not isinstance(domain, AlgebraicScheme_subscheme_affine): raise ValueError('"domain" must be an affine scheme') if R not in Fields(): return typecall(cls, polys, domain) if is_FiniteField(R): return DynamicalSystem_affine_finite_field(polys, domain) return DynamicalSystem_affine_field(polys, domain)
def __classcall_private__(cls, morphism_or_polys, domain=None): r""" Return the appropriate dynamical system on an affine scheme. TESTS:: sage: A.<x> = AffineSpace(ZZ,1) sage: A1.<z> = AffineSpace(CC,1) sage: H = End(A1) sage: f2 = H([z^2+1]) sage: f = DynamicalSystem_affine(f2, A) sage: f.domain() is A False :: sage: P1.<x,y> = ProjectiveSpace(QQ,1) sage: DynamicalSystem_affine([y, 2*x], domain=P1) Traceback (most recent call last): ... ValueError: "domain" must be an affine scheme sage: H = End(P1) sage: DynamicalSystem_affine(H([y, 2*x])) Traceback (most recent call last): ... ValueError: "domain" must be an affine scheme :: sage: R.<x,y,z> = QQ[] sage: f = DynamicalSystem_affine([x+y+z, y*z]) Traceback (most recent call last): ... ValueError: Number of polys does not match dimension of Affine Space of dimension 3 over Rational Field :: sage: A.<x,y> = AffineSpace(QQ,2) sage: f = DynamicalSystem_affine([CC.0*x^2, y^2], domain=A) Traceback (most recent call last): ... TypeError: coefficients of polynomial not in Rational Field """ if isinstance(morphism_or_polys, SchemeMorphism_polynomial): morphism = morphism_or_polys R = morphism.base_ring() polys = list(morphism) domain = morphism.domain() if not is_AffineSpace(domain) and not isinstance( domain, AlgebraicScheme_subscheme_affine): raise ValueError('"domain" must be an affine scheme') if domain != morphism_or_polys.codomain(): raise ValueError('domain and codomain do not agree') if R not in Fields(): return typecall(cls, polys, domain) if is_FiniteField(R): return DynamicalSystem_affine_finite_field(polys, domain) return DynamicalSystem_affine_field(polys, domain) elif isinstance(morphism_or_polys, (list, tuple)): polys = list(morphism_or_polys) else: polys = [morphism_or_polys] PR = get_coercion_model().common_parent(*polys) fraction_field = any(is_FractionField(poly.parent()) for poly in polys) if fraction_field: K = PR.base_ring().fraction_field() # Replace base ring with its fraction field PR = PR.ring().change_ring(K).fraction_field() polys = [PR(poly) for poly in polys] else: quotient_ring = any( is_QuotientRing(poly.parent()) for poly in polys) # If any of the list entries lies in a quotient ring, we try # to lift all entries to a common polynomial ring. if quotient_ring: polys = [PR(poly).lift() for poly in polys] else: polys = [PR(poly) for poly in polys] if domain is None: if PR is SR: raise TypeError("Symbolic Ring cannot be the base ring") if fraction_field: PR = PR.ring() domain = AffineSpace(PR) else: # Check if we can coerce the given polynomials over the given domain PR = domain.ambient_space().coordinate_ring() try: if fraction_field: PR = PR.fraction_field() polys = [PR(poly) for poly in polys] except TypeError: raise TypeError('coefficients of polynomial not in {}'.format( domain.base_ring())) if len(polys) != domain.ambient_space().coordinate_ring().ngens(): raise ValueError( 'Number of polys does not match dimension of {}'.format( domain)) R = domain.base_ring() if R is SR: raise TypeError("Symbolic Ring cannot be the base ring") if not is_AffineSpace(domain) and not isinstance( domain, AlgebraicScheme_subscheme_affine): raise ValueError('"domain" must be an affine scheme') if R not in Fields(): return typecall(cls, polys, domain) if is_FiniteField(R): return DynamicalSystem_affine_finite_field(polys, domain) return DynamicalSystem_affine_field(polys, domain)
def __classcall__(cls, *args, **options): instance = typecall(cls, *args, **options) assert isinstance(instance, cls) instance._init_args = (cls, args, options) return instance
def __classcall_private__(cls, data=None, index_set=None, cartan_type=None, cartan_type_check=True): """ Normalize input so we can inherit from sparse integer matrix. .. NOTE:: To disable the Cartan type check, use the optional argument ``cartan_type_check = False``. EXAMPLES:: sage: C = CartanMatrix(['A',1,1]) sage: C2 = CartanMatrix([[2, -2], [-2, 2]]) sage: C3 = CartanMatrix(matrix([[2, -2], [-2, 2]]), [0, 1]) sage: C == C2 and C == C3 True TESTS: Check that :trac:`15740` is fixed:: sage: d = DynkinDiagram() sage: d.add_edge('a', 'b', 2) sage: d.index_set() ('a', 'b') sage: cm = CartanMatrix(d) sage: cm.index_set() ('a', 'b') """ # Special case with 0 args and kwds has Cartan type if cartan_type is not None and data is None: data = CartanType(cartan_type) if data is None: data = [] n = 0 index_set = tuple() cartan_type = None subdivisions = None elif isinstance(data, CartanMatrix): if index_set is not None: d = {a: index_set[i] for i, a in enumerate(data.index_set())} return data.relabel(d) return data else: dynkin_diagram = None subdivisions = None from sage.combinat.root_system.dynkin_diagram import DynkinDiagram_class if isinstance(data, DynkinDiagram_class): dynkin_diagram = data cartan_type = data._cartan_type else: try: cartan_type = CartanType(data) dynkin_diagram = cartan_type.dynkin_diagram() except (TypeError, ValueError): pass if dynkin_diagram is not None: n = dynkin_diagram.rank() index_set = dynkin_diagram.index_set() oir = dynkin_diagram.odd_isotropic_roots() reverse = {a: i for i, a in enumerate(index_set)} data = {(i, i): 2 if index_set[i] not in oir else 0 for i in range(n)} for (i, j, l) in dynkin_diagram.edge_iterator(): data[(reverse[j], reverse[i])] = -l else: M = matrix(data) if not is_generalized_cartan_matrix(M): raise ValueError( "the input matrix is not a generalized Cartan matrix") n = M.ncols() data = M.dict() subdivisions = M._subdivisions if index_set is None: index_set = tuple(range(n)) else: index_set = tuple(index_set) if len(index_set) != n and len(set(index_set)) != n: raise ValueError("the given index set is not valid") # We can do the Cartan type initialization later as this is not # a unique representation mat = typecall(cls, MatrixSpace(ZZ, n, sparse=True), data, False, True) # FIXME: We have to initialize the CartanMatrix part separately because # of the __cinit__ of the matrix. We should get rid of this workaround mat._CM_init(cartan_type, index_set, cartan_type_check) mat._subdivisions = subdivisions return mat
def __classcall_private__(cls, morphism_or_polys, domain=None): r""" Return the appropriate dynamical system on an affine scheme. TESTS:: sage: A.<x> = AffineSpace(ZZ,1) sage: A1.<z> = AffineSpace(CC,1) sage: H = End(A1) sage: f2 = H([z^2+1]) sage: f = DynamicalSystem_affine(f2, A) sage: f.domain() is A False :: sage: P1.<x,y> = ProjectiveSpace(QQ,1) sage: DynamicalSystem_affine([y, 2*x], domain=P1) Traceback (most recent call last): ... ValueError: "domain" must be an affine scheme sage: H = End(P1) sage: DynamicalSystem_affine(H([y, 2*x])) Traceback (most recent call last): ... ValueError: "domain" must be an affine scheme """ if isinstance(morphism_or_polys, SchemeMorphism_polynomial): morphism = morphism_or_polys R = morphism.base_ring() polys = list(morphism) domain = morphism.domain() if not is_AffineSpace(domain) and not isinstance(domain, AlgebraicScheme_subscheme_affine): raise ValueError('"domain" must be an affine scheme') if domain != morphism_or_polys.codomain(): raise ValueError('domain and codomain do not agree') if R not in Fields(): return typecall(cls, polys, domain) if is_FiniteField(R): return DynamicalSystem_affine_finite_field(polys, domain) return DynamicalSystem_affine_field(polys, domain) elif isinstance(morphism_or_polys,(list, tuple)): polys = list(morphism_or_polys) else: polys = [morphism_or_polys] # We now arrange for all of our list entries to lie in the same ring # Fraction field case first fraction_field = False for poly in polys: P = poly.parent() if is_FractionField(P): fraction_field = True break if fraction_field: K = P.base_ring().fraction_field() # Replace base ring with its fraction field P = P.ring().change_ring(K).fraction_field() polys = [P(poly) for poly in polys] else: # If any of the list entries lies in a quotient ring, we try # to lift all entries to a common polynomial ring. quotient_ring = False for poly in polys: P = poly.parent() if is_QuotientRing(P): quotient_ring = True break if quotient_ring: polys = [P(poly).lift() for poly in polys] else: poly_ring = False for poly in polys: P = poly.parent() if is_PolynomialRing(P) or is_MPolynomialRing(P): poly_ring = True break if poly_ring: polys = [P(poly) for poly in polys] if domain is None: f = polys[0] CR = f.parent() if CR is SR: raise TypeError("Symbolic Ring cannot be the base ring") if fraction_field: CR = CR.ring() domain = AffineSpace(CR) R = domain.base_ring() if R is SR: raise TypeError("Symbolic Ring cannot be the base ring") if not is_AffineSpace(domain) and not isinstance(domain, AlgebraicScheme_subscheme_affine): raise ValueError('"domain" must be an affine scheme') if R not in Fields(): return typecall(cls, polys, domain) if is_FiniteField(R): return DynamicalSystem_affine_finite_field(polys, domain) return DynamicalSystem_affine_field(polys, domain)