Ticket #9502: trac_9502_basis_parent_bug_in_FreeModule.patch
File trac_9502_basis_parent_bug_in_FreeModule.patch, 9.3 KB (added by , 13 years ago) |
---|
-
sage/modules/free_module.py
# HG changeset patch # User Andrey Novoseltsev <novoselt@gmail.com> # Date 1279179043 21600 # Node ID 107b5400a52384feccc640b7d38efa66e092abd1 # Parent 92183851e6cf5a384c5a2842a7295437643f12ff Trac 9502: Echelonized bases of submodules with user bases had wrong parents. diff -r 92183851e6cf -r 107b5400a523 sage/modules/free_module.py
a b 176 176 import sage.rings.infinity 177 177 import sage.rings.integer 178 178 import sage.structure.parent_gens as gens 179 from sage.categories.principal_ideal_domains import PrincipalIdealDomains 179 180 from sage.misc.randstate import current_randstate 180 181 from sage.structure.sequence import Sequence 181 182 … … 1942 1943 sage: FreeModule(PolynomialRing(GF(7),'x'), 2) 1943 1944 Ambient free module of rank 2 over the principal ideal domain Univariate Polynomial Ring in x over Finite Field of size 7 1944 1945 """ 1945 if not isinstance(base_ring, principal_ideal_domain.PrincipalIdealDomain): 1946 raise TypeError, "The base_ring must be a principal ideal domain." 1947 FreeModule_generic.__init__(self, base_ring, rank, degree, sparse) 1946 # The first check should go away once everything is categorized... 1947 if (not isinstance(base_ring, 1948 principal_ideal_domain.PrincipalIdealDomain) 1949 and base_ring not in PrincipalIdealDomains()): 1950 raise TypeError("The base_ring must be a principal ideal domain.") 1951 super(FreeModule_generic_pid, self).__init__(base_ring, rank, degree, 1952 sparse) 1948 1953 1949 1954 def scale(self, other): 1950 1955 """ … … 4534 4539 ############################################################################### 4535 4540 4536 4541 class FreeModule_submodule_with_basis_pid(FreeModule_generic_pid): 4537 """ 4538 An `R`-submodule of `K^n` with distinguished basis, 4539 where `K` is the fraction field of a principal ideal domain 4540 `R`. 4541 """ 4542 def __init__(self, ambient, basis, check=True, 4542 r""" 4543 Construct a submodule of a free module over PID with a distiguished basis. 4544 4545 INPUT: 4546 4547 - ``ambient`` -- ambient free module over a principal ideal domain `R`, 4548 i.e. `R^n`; 4549 4550 - ``basis`` -- list of elements of `K^n`, where `K` is the fraction field 4551 of `R`. These elements must be linearly independent and will be used as 4552 the default basis of the constructed submodule; 4553 4554 - ``check`` -- (default: ``True``) if ``False``, correctness of the input 4555 will not be checked and type conversion may be omitted, use with care; 4556 4557 - ``echelonize`` -- (default:``False``) if ``True``, ``basis`` will be 4558 echelonized and the result will be used as the default basis of the 4559 constructed submodule; 4560 4561 - `` echelonized_basis`` -- (default: ``None``) if not ``None``, must be 4562 the echelonized basis spanning the same submodule as ``basis``; 4563 4564 - ``already_echelonized`` -- (default: ``False``) if ``True``, ``basis`` 4565 must be already given in the echelonized form. 4566 4567 OUTPUT: 4568 4569 - `R`-submodule of `K^n` with the user-specified ``basis``. 4570 4571 EXAMPLES:: 4572 4573 sage: M = ZZ^3 4574 sage: W = M.span_of_basis([[1,2,3],[4,5,6]]); W 4575 Free module of degree 3 and rank 2 over Integer Ring 4576 User basis matrix: 4577 [1 2 3] 4578 [4 5 6] 4579 4580 Now we create a submodule of the ambient vector space, rather than 4581 ``M`` itself:: 4582 4583 sage: W = M.span_of_basis([[1,2,3/2],[4,5,6]]); W 4584 Free module of degree 3 and rank 2 over Integer Ring 4585 User basis matrix: 4586 [ 1 2 3/2] 4587 [ 4 5 6] 4588 """ 4589 4590 def __init__(self, ambient, basis, check=True, 4543 4591 echelonize=False, echelonized_basis=None, already_echelonized=False): 4544 """ 4545 Create a free module with basis over a PID. 4546 4547 EXAMPLES:: 4548 4549 sage: M = ZZ^3 4550 sage: W = M.span_of_basis([[1,2,3],[4,5,6]]); W 4592 r""" 4593 See :class:`FreeModule_submodule_with_basis_pid` for documentation. 4594 4595 TESTS:: 4596 4597 sage: M = ZZ^3 4598 sage: W = M.span_of_basis([[1,2,3],[4,5,6]]) 4599 sage: TestSuite(W).run() 4600 4601 We test that the issue at Trac #9502 is solved:: 4602 4603 sage: parent(W.basis()[0]) 4551 4604 Free module of degree 3 and rank 2 over Integer Ring 4552 4605 User basis matrix: 4553 4606 [1 2 3] 4554 4607 [4 5 6] 4555 4556 :: 4557 4558 sage: W = M.span_of_basis([[1,2,3/2],[4,5,6]]); W 4559 Free module of degree 3 and rank 2 over Integer Ring 4560 User basis matrix: 4561 [ 1 2 3/2] 4562 [ 4 5 6] 4608 sage: parent(W.echelonized_basis()[0]) 4609 Free module of degree 3 and rank 2 over Integer Ring 4610 User basis matrix: 4611 [1 2 3] 4612 [4 5 6] 4563 4613 """ 4564 4614 if not isinstance(ambient, FreeModule_ambient_pid): 4565 raise TypeError, "ambient (=%s) must be ambient."%ambient 4615 raise TypeError("ambient (=%s) must be ambient." % ambient) 4616 self.__ambient_module = ambient 4566 4617 if not isinstance(basis, (list, tuple)): 4567 raise TypeError , "basis (=%s) must be a list"%basis4618 raise TypeError("basis (=%s) must be a list" % basis) 4568 4619 basis = list(basis) # make it a list rather than a tuple 4569 4620 if check: 4570 V = ambient.vector_space()4571 basis = [V(x) for x in basis]4572 4573 self.__ambient_module = ambient4574 4575 if check:4576 4621 V = ambient.ambient_vector_space() 4577 4622 for i in range(len(basis)): 4578 4623 x = basis[i] 4579 if not (x in V):4624 if x not in V: 4580 4625 try: 4581 4626 basis[i] = V(x) 4582 4627 except TypeError: 4583 raise TypeError, "each element of basis must be in the ambient vector space" 4584 R = ambient.base_ring() 4585 4628 raise TypeError("each element of basis must be in " 4629 "the ambient vector space") 4586 4630 if echelonize and not already_echelonized: 4587 4631 basis = self._echelonized_basis(ambient, basis) 4588 4589 FreeModule_generic.__init__(self, R, rank=len(basis), degree=ambient.degree(), sparse=ambient.is_sparse()) 4590 4632 R = ambient.base_ring() 4633 # The following is WRONG - we should call __init__ of 4634 # FreeModule_generic_pid. However, it leads to a bunch of errors. 4635 FreeModule_generic.__init__(self, R, 4636 rank=len(basis), degree=ambient.degree(), 4637 sparse=ambient.is_sparse()) 4591 4638 C = self.element_class() 4592 4639 try: 4593 w = [C(self, x.list(), 4594 coerce=False, copy=True) for x in basis] 4640 w = [C(self, x.list(), coerce=False, copy=True) for x in basis] 4595 4641 except TypeError: 4596 4642 C = element_class(R.fraction_field(), self.is_sparse()) 4597 4643 self._element_class = C 4598 w = [C(self, x.list(), 4599 coerce=False, copy=True) for x in basis] 4644 w = [C(self, x.list(), coerce=False, copy=True) for x in basis] 4600 4645 self.__basis = basis_seq(self, w) 4601 4646 4602 if echelonized_basis != None: 4603 4604 self.__echelonized_basis = basis_seq(self, echelonized_basis) 4605 4606 else: 4607 4608 if echelonize or already_echelonized: 4609 self.__echelonized_basis = self.__basis 4610 else: 4611 w = self._echelonized_basis(ambient, basis) 4612 self.__echelonized_basis = basis_seq(self, w) 4613 4647 if echelonize or already_echelonized: 4648 self.__echelonized_basis = self.__basis 4649 else: 4650 if echelonized_basis is None: 4651 echelonized_basis = self._echelonized_basis(ambient, basis) 4652 w = [C(self, x.list(), coerce=False, copy=True) 4653 for x in echelonized_basis] 4654 self.__echelonized_basis = basis_seq(self, w) 4614 4655 if check and len(basis) != len(self.__echelonized_basis): 4615 raise ValueError, "The given basis vectors must be linearly independent." 4656 raise ValueError("The given basis vectors must be linearly " 4657 "independent.") 4616 4658 4617 4659 def __hash__(self): 4618 4660 """ -
sage/symbolic/ring.pyx
diff -r 92183851e6cf -r 107b5400a523 sage/symbolic/ring.pyx
a b 31 31 from sage.structure.element cimport RingElement, Element 32 32 from sage.structure.parent_base import ParentWithBase 33 33 from sage.rings.ring cimport CommutativeRing 34 from sage.categories.all import Fields 34 35 from sage.categories.morphism cimport Morphism 35 36 36 from sage.rings.all import RR, CC 37 37 38 38 pynac_symbol_registry = {} … … 50 50 sage: sage.symbolic.ring.SymbolicRing() 51 51 Symbolic Ring 52 52 """ 53 ParentWithBase.__init__(self, self )53 ParentWithBase.__init__(self, self, category=Fields()) 54 54 self._populate_coercion_lists_(convert_method_name='_symbolic_') 55 55 56 56 def __reduce__(self):