| 1690 | def __abs__(self): |
| 1691 | """ |
| 1692 | EXAMPLES:: |
| 1693 | |
| 1694 | sage: K.<a> = QuadraticField(2, 'a', embedding=-1.4142) |
| 1695 | sage: abs(a) # indirect test |
| 1696 | -a |
| 1697 | sage: abs(a+1) # indirect test |
| 1698 | -a - 1 |
| 1699 | sage: abs(a+2) # indirect test |
| 1700 | a + 2 |
| 1701 | |
| 1702 | sage: K.<a> = NumberField(x^2+1, embedding=CDF.gen()) |
| 1703 | sage: abs(a+1) |
| 1704 | sqrt(2) |
| 1705 | """ |
| 1706 | if mpz_sgn(self.D.value) == 1: |
| 1707 | if self.sign() >= 0: |
| 1708 | return self |
| 1709 | return -self |
| 1710 | |
| 1711 | # doing that way the parent is the symbolic ring (or IntegerRing if the |
| 1712 | # norm of self is a square). On the other hand, it is coherent with |
| 1713 | # sage.rings.integer.Integer.sqrt |
| 1714 | return (self.real()**2 + self.imag()**2).sqrt() |
| 1715 | |
| 1716 | def floor(self): |
| 1717 | r""" |
| 1718 | Returns the floor of x. |
| 1719 | |
| 1720 | EXAMPLES:: |
| 1721 | |
| 1722 | sage: K.<sqrt2> = QuadraticField(2,name='sqrt2') |
| 1723 | sage: sqrt2.floor() |
| 1724 | 1 |
| 1725 | sage: (-sqrt2).floor() |
| 1726 | -2 |
| 1727 | sage: (13/197 + 3702/123*sqrt2).floor() |
| 1728 | 42 |
| 1729 | sage: (13/197-3702/123*sqrt2).floor() |
| 1730 | -43 |
| 1731 | |
| 1732 | TESTS:: |
| 1733 | |
| 1734 | sage: K2.<sqrt2> = QuadraticField(2) |
| 1735 | sage: K3.<sqrt3> = QuadraticField(3) |
| 1736 | sage: K5.<sqrt5> = QuadraticField(5) |
| 1737 | sage: for _ in xrange(100): |
| 1738 | ....: a = QQ.random_element(1000,20) |
| 1739 | ....: b = QQ.random_element(1000,20) |
| 1740 | ....: assert floor(a+b*sqrt(2.)) == floor(a+b*sqrt2) |
| 1741 | ....: assert floor(a+b*sqrt(3.)) == floor(a+b*sqrt3) |
| 1742 | ....: assert floor(a+b*sqrt(5.)) == floor(a+b*sqrt5) |
| 1743 | |
| 1744 | sage: K = QuadraticField(-2) |
| 1745 | sage: l = [K(52), K(-3), K(43/12), K(-43/12)] |
| 1746 | sage: [x.floor() for x in l] |
| 1747 | [52, -3, 3, -4] |
| 1748 | """ |
| 1749 | cdef mpz_t x |
| 1750 | cdef Integer result |
| 1751 | |
| 1752 | if mpz_sgn(self.b) == 0: |
| 1753 | mpz_init_set(x,self.a) |
| 1754 | mpz_fdiv_q(x,x,self.denom) |
| 1755 | result = PY_NEW(Integer) |
| 1756 | mpz_set(result.value,x) |
| 1757 | mpz_clear(x) |
| 1758 | return result |
| 1759 | |
| 1760 | if not mpz_sgn(self.D.value) == 1: |
| 1761 | raise ValueError("floor is not defined for complex quadratic number field") |
| 1762 | |
| 1763 | mpz_init(x) |
| 1764 | mpz_mul(x,self.b,self.b) |
| 1765 | mpz_mul(x,x,self.D.value) |
| 1766 | mpz_sqrt(x,x) |
| 1767 | if mpz_sgn(self.b) == -1: |
| 1768 | if self.standard_embedding: |
| 1769 | mpz_neg(x,x) |
| 1770 | mpz_sub_ui(x,x,1) |
| 1771 | elif not self.standard_embedding: |
| 1772 | mpz_neg(x,x) |
| 1773 | mpz_sub_ui(x,x,1) |
| 1774 | |
| 1775 | mpz_add(x,x,self.a) # here x = a + floor(sqrt(b^2 D)) or a + floor(-sqrt(b^2 D)) |
| 1776 | mpz_fdiv_q(x,x,self.denom) |
| 1777 | result = PY_NEW(Integer) |
| 1778 | mpz_set(result.value,x) |
| 1779 | mpz_clear(x) |
| 1780 | return result |
| 1781 | |
| 1782 | def ceil(self): |
| 1783 | r""" |
| 1784 | Returns the ceil. |
| 1785 | |
| 1786 | EXAMPLES:: |
| 1787 | |
| 1788 | sage: K.<sqrt7> = QuadraticField(7, name='sqrt7') |
| 1789 | sage: sqrt7.ceil() |
| 1790 | 3 |
| 1791 | sage: (-sqrt7).ceil() |
| 1792 | -2 |
| 1793 | sage: (1022/313*sqrt7 - 14/23).ceil() |
| 1794 | 9 |
| 1795 | |
| 1796 | TESTS:: |
| 1797 | |
| 1798 | sage: K2.<sqrt2> = QuadraticField(2) |
| 1799 | sage: K3.<sqrt3> = QuadraticField(3) |
| 1800 | sage: K5.<sqrt5> = QuadraticField(5) |
| 1801 | sage: for _ in xrange(100): |
| 1802 | ....: a = QQ.random_element(1000,20) |
| 1803 | ....: b = QQ.random_element(1000,20) |
| 1804 | ....: assert ceil(a+b*sqrt(2.)) == ceil(a+b*sqrt2) |
| 1805 | ....: assert ceil(a+b*sqrt(3.)) == ceil(a+b*sqrt3) |
| 1806 | ....: assert ceil(a+b*sqrt(5.)) == ceil(a+b*sqrt5) |
| 1807 | |
| 1808 | sage: K = QuadraticField(-2) |
| 1809 | sage: l = [K(52), K(-3), K(43/12), K(-43/12)] |
| 1810 | sage: [x.ceil() for x in l] |
| 1811 | [52, -3, 4, -3] |
| 1812 | """ |
| 1813 | x = self.floor() |
| 1814 | if mpz_sgn(self.b) == 0 and mpz_cmp_ui(self.denom,1) == 0: |
| 1815 | return x |
| 1816 | return x+1 |
| 1817 | |