Ticket #13256: trac_13256-abs_floor_ceil_in_quadratic_fields.patch

File trac_13256-abs_floor_ceil_in_quadratic_fields.patch, 5.7 KB (added by vdelecroix, 7 years ago)
  • sage/rings/number_field/number_field_element_quadratic.pyx

    # HG changeset patch
    # User Vincent Delecroix <20100.delecroix at gmail.com>
    # Date 1368883037 -7200
    # Node ID c5e06843aaa70493901be340b455a0bb7e6cadfc
    # Parent  40c05c8d8f8ad967606d2b43e82fd26586849aff
    ticket 13256
    
    Implement abs, floor and ceil for quadratic number field elements.
    
    diff --git a/sage/rings/number_field/number_field_element_quadratic.pyx b/sage/rings/number_field/number_field_element_quadratic.pyx
    a b  
    99- Robert Bradshaw (2007-09): Initial version
    1010- David Harvey (2007-10): fix up a few bugs, polish around the edges
    1111- David Loeffler (2009-05): add more documentation and tests
    12 - Vincent Delecroix (2012-07): comparisons for quadratic number fields (#13213)
     12- Vincent Delecroix (2012-07): comparisons for quadratic number fields (#13213),
     13  abs, floor and ceil functions (#13256)
    1314
    1415TODO:
    1516
     
    3536include "../../ext/stdsage.pxi"
    3637
    3738from sage.structure.element cimport Element
     39from sage.rings.integer cimport Integer
    3840
    3941from sage.rings.integer_ring import ZZ
    4042from sage.rings.rational_field import QQ
     
    14161418                mpz_neg(q.b, self.b)
    14171419            return q
    14181420
    1419     def __abs__(self):
    1420         """
    1421         EXAMPLES::
    1422 
    1423             sage: K.<a> = NumberField(x^2+1, embedding=CDF.gen())
    1424             sage: abs(a+1)
    1425             sqrt(2)
    1426         """
    1427         return (self.imag()**2 + self.real()**2).sqrt()
    1428 
    14291421    def _coefficients(self):
    14301422        """
    14311423        EXAMPLES::
     
    16951687        else:
    16961688            return self.charpoly(var)
    16971689
     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
    16981818
    16991819cdef class OrderElement_quadratic(NumberFieldElement_quadratic):
    17001820    """