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) |
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, |
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]) |
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()) |
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) |