Exemplo n.º 1
0
    def random_isometry(self, preserve_orientation=True, **kwargs):
        r"""
        Return a random isometry in the Upper Half Plane model.

        INPUT:

        - ``preserve_orientation`` -- if ``True`` return an
          orientation-preserving isometry

        OUTPUT:

        - a hyperbolic isometry

        EXAMPLES::

            sage: A = HyperbolicPlane().UHP().random_isometry()
            sage: B = HyperbolicPlane().UHP().random_isometry(preserve_orientation=False)
            sage: B.preserves_orientation()
            False
        """
        [a, b, c, d] = [RR.random_element() for k in range(4)]
        while abs(a * d - b * c) < EPSILON:
            [a, b, c, d] = [RR.random_element() for k in range(4)]
        M = matrix(RDF, 2, [a, b, c, d])
        M = M / (M.det()).abs().sqrt()
        if M.det() > 0:
            if not preserve_orientation:
                M = M * matrix(2, [0, 1, 1, 0])
        elif preserve_orientation:
            M = M * matrix(2, [0, 1, 1, 0])
        return self._Isometry(self, M, check=False)
Exemplo n.º 2
0
    def _compute_power_series(self, n, abs_prec, cache_ring=None):
        """
        Compute the power series giving Dickman's function on [n, n+1], by
        recursion in n. For internal use; self.power_series() is a wrapper
        around this intended for the user.

        INPUT:

        -  ``n`` - the lower endpoint of the interval for which
           this power series holds

        -  ``abs_prec`` - the absolute precision of the
           resulting power series

        -  ``cache_ring`` - for internal use, caches the power
           series at this precision.

        EXAMPLES::

            sage: f = dickman_rho.power_series(2, 20); f
            -9.9376e-8*x^11 + 3.7722e-7*x^10 - 1.4684e-6*x^9 + 5.8783e-6*x^8 - 0.000024259*x^7 + 0.00010341*x^6 - 0.00045583*x^5 + 0.0020773*x^4 - 0.0097336*x^3 + 0.045224*x^2 - 0.11891*x + 0.13032
        """
        if n <= 1:
            if n <= -1:
                return PolynomialRealDense(RealField(abs_prec)['x'])
            if n == 0:
                return PolynomialRealDense(RealField(abs_prec)['x'], [1])
            elif n == 1:
                nterms = (RDF(abs_prec) * RDF(2).log() / RDF(3).log()).ceil()
                R = RealField(abs_prec)
                neg_three = ZZ(-3)
                coeffs = [1 - R(1.5).log()
                          ] + [neg_three**-k / k for k in range(1, nterms)]
                f = PolynomialRealDense(R['x'], coeffs)
                if cache_ring is not None:
                    self._f[n] = f.truncate_abs(f[0] >> (
                        cache_ring.prec() + 1)).change_ring(cache_ring)
                return f
        else:
            f = self._compute_power_series(n - 1, abs_prec, cache_ring)
            # integrand = f / (2n+1 + x)
            # We calculate this way because the most significant term is the constant term,
            # and so we want to push the error accumulation and remainder out to the least
            # significant terms.
            integrand = f.reverse().quo_rem(
                PolynomialRealDense(f.parent(), [1, 2 * n + 1]))[0].reverse()
            integrand = integrand.truncate_abs(RR(2)**-abs_prec)
            iintegrand = integrand.integral()
            ff = PolynomialRealDense(f.parent(),
                                     [f(1) + iintegrand(-1)]) - iintegrand
            i = 0
            while abs(f[i]) < abs(f[i + 1]):
                i += 1
            rel_prec = int(abs_prec + abs(RR(f[i])).log2())
            if cache_ring is not None:
                self._f[n] = ff.truncate_abs(
                    ff[0] >> (cache_ring.prec() + 1)).change_ring(cache_ring)
            return ff.change_ring(RealField(rel_prec))
Exemplo n.º 3
0
    def plot_histogram(self, clr=(0, 0, 1), eps=0.4):
        """
        Plots the histogram plot of the sequence, which is assumed to be real
        or from a finite field, with a real indexing set I coercible into RR.
        Options are clr, which is an RGB value, and eps, which is the spacing between the 
        bars.

        EXAMPLES:
            sage: J = range(3)
            sage: A = [ZZ(i^2)+1 for i in J]
            sage: s = IndexedSequence(A,J)
            sage: P = s.plot_histogram()

        Now type show(P) to view this in a browser.
        """
        #from sage.plot.misc import text
        F = self.base_ring()  ## elements must be coercible into RR
        I = self.index_object()
        N = len(I)
        S = self.list()
        P = [
            polygon([[RR(I[i]) - eps, 0], [
                RR(I[i]) - eps, RR(S[i])
            ], [RR(I[i]) + eps, RR(S[i])], [RR(I[i]) + eps, 0], [RR(I[i]), 0]],
                    rgbcolor=clr) for i in range(N)
        ]
        T = [
            text(str(I[i]), (RR(I[i]), -0.8), fontsize=15, rgbcolor=(1, 0, 0))
            for i in range(N)
        ]
        return sum(P) + sum(T)
Exemplo n.º 4
0
Arquivo: dft.py Projeto: wdv4758h/sage
    def plot_histogram(self, clr=(0, 0, 1), eps=0.4):
        r"""
        Plot the histogram plot of the sequence.

        The sequence is assumed to be real or from a finite field,
        with a real indexing set ``I`` coercible into `\RR`.

        Options are ``clr``, which is an RGB value, and ``eps``, which
        is the spacing between the bars.

        EXAMPLES::

            sage: J = range(3)
            sage: A = [ZZ(i^2)+1 for i in J]
            sage: s = IndexedSequence(A,J)
            sage: P = s.plot_histogram()
            sage: show(P) # Not tested
        """
        # elements must be coercible into RR
        I = self.index_object()
        N = len(I)
        S = self.list()
        P = [
            polygon([[RR(I[i]) - eps, 0], [
                RR(I[i]) - eps, RR(S[i])
            ], [RR(I[i]) + eps, RR(S[i])], [RR(I[i]) + eps, 0], [RR(I[i]), 0]],
                    rgbcolor=clr) for i in range(N)
        ]
        T = [
            text(str(I[i]), (RR(I[i]), -0.8), fontsize=15, rgbcolor=(1, 0, 0))
            for i in range(N)
        ]
        return sum(P) + sum(T)
Exemplo n.º 5
0
def get_classified_solution_dicts(output_file_contents,
                                  input_ring,
                                  get_failures=True):
    """
    Returns a dictionary of lists of dictionaries of variable:value (key:value)
    pairs.  Only used internally; see the classified_solution_dict function in
    the PHC_Object class definition for details.

    INPUT:

    - output_file_contents -- phc solution output as a string
    - input_ring -- a PolynomialRing that variable names can be coerced into

    OUTPUT:

    - a dictionary of lists if dictionaries of solutions, classifies by type

    EXAMPLES::

        sage: from sage.interfaces.phc import *
        sage: R2.<x1,x2> = PolynomialRing(QQ,2)
        sage: test_sys = [(x1-2)^5-x2, (x2-1)^5-1]
        sage: sol = phc.blackbox(test_sys, R2)          # optional -- phc
        sage: sol_classes = get_classified_solution_dicts(sol.output_file_contents,R2)  # optional -- phc
        sage: len(sol_classes['real'])            # optional -- phc
        1
    """
    output_list = output_file_contents.splitlines()
    test = 'False'
    solution_dicts = {}
    solution_types = ['complex', 'real', 'failure']
    for sol_type in solution_types:
        solution_dicts[sol_type] = []
    for solution_line in range(len(output_list) - 1, -1, -1):
        if output_list[solution_line].find('THE SOLUTIONS') == 0:
            break
    var_number = int(output_list[solution_line + 2].split(' ')[1])
    sol_number = int(output_list[solution_line + 2].split(' ')[0])
    for i in range(solution_line + 1, len(output_list)):
        if output_list[i].count('the solution for t') == 1:
            phc_type = output_list[i + var_number + 1].split(' = ')[-1]
            if phc_type.find('complex') != -1:
                phc_type = 'complex'
            elif phc_type.find('real') != -1:
                phc_type = 'real'
            else:
                phc_type = 'failure'
            temp_dict = {}
            for j in range(1, var_number + 1):
                rawsplit = output_list[i + j].split(': ')[1].split(' ')
                for extras in range(rawsplit.count('')):
                    rawsplit.remove('')
                temp_var = output_list[i + j].split(': ')[0].replace(' ', '')
                if phc_type == 'real':
                    temp_dict[input_ring(temp_var)] = RR(rawsplit[0])
                else:
                    temp_dict[input_ring(temp_var)] = CC(
                        rawsplit[0], rawsplit[1])
            solution_dicts[phc_type].append(temp_dict)
    return solution_dicts
Exemplo n.º 6
0
    def approximate(self, x, parent=None):
        r"""
        Approximate using de Bruijn's formula

        .. MATH::

             \rho(x) \sim \frac{exp(-x \xi + Ei(\xi))}{\sqrt{2\pi x}\xi}

        which is asymptotically equal to Dickman's function, and is much
        faster to compute.

        REFERENCES:

        - N. De Bruijn, "The Asymptotic behavior of a function
          occurring in the theory of primes." J. Indian Math Soc. v 15.
          (1951)

        EXAMPLES::

            sage: dickman_rho.approximate(10)
            2.41739196365564e-11
            sage: dickman_rho(10)
            2.77017183772596e-11
            sage: dickman_rho.approximate(1000)
            4.32938809066403e-3464
        """
        log, exp, sqrt, pi = math.log, math.exp, math.sqrt, math.pi
        x = float(x)
        xi = log(x)
        y = (exp(xi) - 1.0) / xi - x
        while abs(y) > 1e-12:
            dydxi = (exp(xi) * (xi - 1.0) + 1.0) / (xi * xi)
            xi -= y / dydxi
            y = (exp(xi) - 1.0) / xi - x
        return (-x * xi + RR(xi).eint()).exp() / (sqrt(2 * pi * x) * xi)
Exemplo n.º 7
0
    def __float__(self):
        r"""
        TESTS::

            sage: float(E(7) + E(7,6))
            1.246979603717467
        """
        from sage.rings.real_mpfr import RR
        return float(RR(self))
Exemplo n.º 8
0
    def local_coordinates_at_infinity(self, prec=20, name='t'):
        """
        For the genus `g` hyperelliptic curve `y^2 = f(x)`, return
        `(x(t), y(t))` such that `(y(t))^2 = f(x(t))`, where `t = x^g/y` is
        the local parameter at infinity

        INPUT:

        - ``prec`` -- desired precision of the local coordinates
        - ``name`` -- generator of the power series ring (default: ``t``)

        OUTPUT:

        `(x(t),y(t))` such that `y(t)^2 = f(x(t))` and `t = x^g/y`
        is the local parameter at infinity

        EXAMPLES::

            sage: R.<x> = QQ['x']
            sage: H = HyperellipticCurve(x^5-5*x^2+1)
            sage: x,y = H.local_coordinates_at_infinity(10)
            sage: x
            t^-2 + 5*t^4 - t^8 - 50*t^10 + O(t^12)
            sage: y
            t^-5 + 10*t - 2*t^5 - 75*t^7 + 50*t^11 + O(t^12)

        ::

            sage: R.<x> = QQ['x']
            sage: H = HyperellipticCurve(x^3-x+1)
            sage: x,y = H.local_coordinates_at_infinity(10)
            sage: x
            t^-2 + t^2 - t^4 - t^6 + 3*t^8 + O(t^12)
            sage: y
            t^-3 + t - t^3 - t^5 + 3*t^7 - 10*t^11 + O(t^12)

        AUTHOR:

        - Jennifer Balakrishnan (2007-12)
        """
        g = self.genus()
        pol = self.hyperelliptic_polynomials()[0]
        K = LaurentSeriesRing(self.base_ring(), name, default_prec=prec + 2)
        t = K.gen()
        L = PolynomialRing(K, 'x')
        x = L.gen()
        i = 0
        w = (x**g / t)**2 - pol
        wprime = w.derivative(x)
        if pol.degree() == 2 * g + 1:
            x = t**-2
        else:
            x = t**-1
        for i in range((RR(log(prec + 2) / log(2))).ceil()):
            x = x - w(x) / wprime(x)
        y = x**g / t
        return x + O(t**(prec + 2)), y + O(t**(prec + 2))
Exemplo n.º 9
0
    def plot(self):
        """
        Plot the points of the sequence.

        Elements of the sequence are assumed to be real or from a
        finite field, with a real indexing set ``I = range(len(self))``.

        EXAMPLES::

            sage: I = range(3)
            sage: A = [ZZ(i^2)+1 for i in I]
            sage: s = IndexedSequence(A,I)
            sage: P = s.plot()
            sage: show(P) # Not tested
        """
        # elements must be coercible into RR
        I = self.index_object()
        S = self.list()
        return line([[RR(I[i]),RR(S[i])] for i in range(len(I)-1)])
Exemplo n.º 10
0
    def random_point(self, **kwargs):
        r"""
        Return a random point in the upper half plane. The points are
        uniformly distributed over the rectangle `[-10, 10] \times [0, 10i]`.

        EXAMPLES::

            sage: p = HyperbolicPlane().UHP().random_point().coordinates()
            sage: bool((p.imag()) > 0)
            True
        """
        # TODO: use **kwargs to allow these to be set
        real_min = -10
        real_max = 10
        imag_min = 0
        imag_max = 10
        p = RR.random_element(min=real_min, max=real_max) \
            + I * RR.random_element(min=imag_min, max=imag_max)
        return self.get_point(p)
Exemplo n.º 11
0
    def dwt(self,other="haar",wavelet_k=2):
        """
        Wraps the gsl WaveletTransform.forward in dwt.pyx (written
        by Joshua Kantor). Assumes the length of the sample is a power of 2.
        Uses the GSL function gsl_wavelet_transform_forward.

        other -- the wavelet_type:   the name of the type of wavelet,
                                     valid choices are:
                                     'daubechies','daubechies_centered',
                                     'haar' (default),'haar_centered',
                                     'bspline', and 'bspline_centered'.

        wavelet_k -- For daubechies wavelets, wavelet_k specifies a
                     daubechie wavelet with k/2 vanishing moments.
                     k = 4,6,...,20 for k even are the only ones implemented.
                     For Haar wavelets, wavelet_k must be 2.
                     For bspline wavelets,
                     wavelet_k = 103,105,202,204,206,208,301,305, 307,309
                     will give biorthogonal B-spline wavelets of order (i,j) where
                     wavelet_k=100*i+j.

        The wavelet transform uses J=log_2(n) levels.

        EXAMPLES:
            sage: J = range(8)
            sage: A = [RR(1) for i in J]
            sage: s = IndexedSequence(A,J)
            sage: t = s.dwt()
            sage: t        # slightly random output
            Indexed sequence: [2.82842712474999, 0.000000000000000, 0.000000000000000, 0.000000000000000, 0.000000000000000, 0.000000000000000, 0.000000000000000, 0.000000000000000]
                indexed by [0, 1, 2, 3, 4, 5, 6, 7]
        """
        F = self.base_ring()   ## elements must be coercible into RR
        J = self.index_object()   ## must be = range(N)
        N = len(J)             ## must be 1 minus a power of 2
        S = self.list()
        if other=="haar" or other=="haar_centered":
            if wavelet_k in [2]:
                a = WaveletTransform(N,other,wavelet_k)
            else:
                raise ValueError,"wavelet_k must be = 2"
        if other=="debauchies" or other=="debauchies_centered":
            if wavelet_k in [4,6,8,10,12,14,16,18,20]:
                a = WaveletTransform(N,other,wavelet_k)
            else:
                raise ValueError,"wavelet_k must be in {4,6,8,10,12,14,16,18,20}"
        if other=="bspline" or other=="bspline_centered":
            if wavelet_k in [103,105,202,204,206,208,301,305,307,309]:
                a = WaveletTransform(N,other,103)
            else:
                raise ValueError,"wavelet_k must be in {103,105,202,204,206,208,301,305,307,309}"
        for i in range(N):
            a[i] = S[i]
        a.forward_transform()
        return IndexedSequence([RR(a[j]) for j in J],J)
Exemplo n.º 12
0
    def local_coordinates_at_nonweierstrass(self, P, prec=20, name='t'):
        """
        For a non-Weierstrass point `P = (a,b)` on the hyperelliptic
        curve `y^2 = f(x)`, return `(x(t), y(t))` such that `(y(t))^2 = f(x(t))`,
        where `t = x - a` is the local parameter.

        INPUT:

        - ``P = (a, b)`` -- a non-Weierstrass point on self
        - ``prec`` --  desired precision of the local coordinates
        - ``name`` -- gen of the power series ring (default: ``t``)

        OUTPUT:

        `(x(t),y(t))` such that `y(t)^2 = f(x(t))` and `t = x - a`
        is the local parameter at `P`

        EXAMPLES::

            sage: R.<x> = QQ['x']
            sage: H = HyperellipticCurve(x^5-23*x^3+18*x^2+40*x)
            sage: P = H(1,6)
            sage: x,y = H.local_coordinates_at_nonweierstrass(P,prec=5)
            sage: x
            1 + t + O(t^5)
            sage: y
            6 + t - 7/2*t^2 - 1/2*t^3 - 25/48*t^4 + O(t^5)
            sage: Q = H(-2,12)
            sage: x,y = H.local_coordinates_at_nonweierstrass(Q,prec=5)
            sage: x
            -2 + t + O(t^5)
            sage: y
            12 - 19/2*t - 19/32*t^2 + 61/256*t^3 - 5965/24576*t^4 + O(t^5)

        AUTHOR:

            - Jennifer Balakrishnan (2007-12)
        """
        d = P[1]
        if d == 0:
            raise TypeError(
                "P = %s is a Weierstrass point. Use local_coordinates_at_weierstrass instead!"
                % P)
        pol = self.hyperelliptic_polynomials()[0]
        L = PowerSeriesRing(self.base_ring(), name)
        t = L.gen()
        L.set_default_prec(prec)
        K = PowerSeriesRing(L, 'x')
        pol = K(pol)
        x = K.gen()
        b = P[0]
        f = pol(t + b)
        for i in range((RR(log(prec) / log(2))).ceil()):
            d = (d + f / d) / 2
        return t + b + O(t**(prec)), d + O(t**(prec))
Exemplo n.º 13
0
    def plot(self):
        """
        Plots the points of the sequence, whose elements are assumed
        to be real or from a finite field, with a real indexing set I
        = range(len(self)).

        EXAMPLES:
            sage: I = range(3)
            sage: A = [ZZ(i^2)+1 for i in I]
            sage: s = IndexedSequence(A,I)
            sage: P = s.plot()

        Now type show(P) to view this in a browser.
        """
        F = self.base_ring()   ## elements must be coercible into RR
        I = self.index_object()
        N = len(I)
        S = self.list()
        P = line([[RR(I[i]),RR(S[i])] for i in range(N-1)])
        return P
Exemplo n.º 14
0
    def _evalf_(self, x, **kwargs):
        """
        EXAMPLES::

            sage: from sage.functions.airy import airy_bi_simple
            sage: airy_bi_simple(0.0)
            0.614926627446001
            sage: airy_bi_simple(1.0 * I)
            0.648858208330395 + 0.344958634768048*I

        We can use several methods for numerical evaluation::

            sage: airy_bi_simple(3).n(algorithm='mpmath')
            14.0373289637302
            sage: airy_bi_simple(3).n(algorithm='mpmath', prec=100)
            14.037328963730232031740267314
            sage: airy_bi_simple(3).n(algorithm='scipy')  # rel tol 1e-10
            14.037328963730136
            sage: airy_bi_simple(I).n(algorithm='scipy')  # rel tol 1e-10
            0.648858208330395 + 0.34495863476804844*I

        TESTS::

            sage: parent(airy_bi_simple(3).n(algorithm='scipy'))
            Real Field with 53 bits of precision
            sage: airy_bi_simple(3).n(algorithm='scipy', prec=200)
            Traceback (most recent call last):
            ...
            NotImplementedError: airy_bi not implemented for precision > 53
        """
        algorithm = kwargs.get('algorithm', 'mpmath') or 'mpmath'
        parent = kwargs.get('parent', None)
        if algorithm == 'scipy':
            if hasattr(parent, 'prec') and parent.prec() > 53:
                raise NotImplementedError("%s not implemented for precision > 53" % self.name())
            from sage.rings.real_mpfr import RR
            from sage.rings.cc import CC
            from sage.functions.other import real, imag
            from scipy.special import airy as airy
            if x in RR:
                y = airy(real(x))[2]
                if parent is None:
                    return RR(y)
            else:
                y = airy(complex(real(x), imag(x)))[2]
                if parent is None:
                    return CC(y)
            return parent(y)
        elif algorithm == 'mpmath':
            import mpmath
            from sage.libs.mpmath import utils as mpmath_utils
            return mpmath_utils.call(mpmath.airybi, x, parent=parent)
        else:
            raise ValueError("unknown algorithm '%s'" % algorithm)
Exemplo n.º 15
0
    def _evalf_(self, x, **kwargs):
        """
        EXAMPLES::

            sage: from sage.functions.airy import airy_ai_simple
            sage: airy_ai_simple(0.0)
            0.355028053887817
            sage: airy_ai_simple(1.0 * I)
            0.331493305432141 - 0.317449858968444*I

        We can use several methods for numerical evaluation::

            sage: airy_ai_simple(3).n(algorithm='mpmath')
            0.00659113935746072
            sage: airy_ai_simple(3).n(algorithm='mpmath', prec=100)
            0.0065911393574607191442574484080
            sage: airy_ai_simple(3).n(algorithm='scipy')  # rel tol 1e-10
            0.006591139357460719
            sage: airy_ai_simple(I).n(algorithm='scipy')  # rel tol 1e-10
            0.33149330543214117 - 0.3174498589684438*I

        TESTS::

            sage: parent(airy_ai_simple(3).n(algorithm='scipy'))
            Real Field with 53 bits of precision
            sage: airy_ai_simple(3).n(algorithm='scipy', prec=200)
            Traceback (most recent call last):
            ...
            NotImplementedError: airy_ai not implemented for precision > 53
        """
        algorithm = kwargs.get('algorithm', 'mpmath') or 'mpmath'
        parent = kwargs.get('parent')
        if algorithm == 'scipy':
            if hasattr(parent, 'prec') and parent.prec() > 53:
                raise NotImplementedError("%s not implemented for precision > 53" % self.name())
            from sage.rings.real_mpfr import RR
            from sage.rings.cc import CC
            from sage.functions.other import real, imag
            from scipy.special import airy as airy
            if x in RR:
                y = airy(real(x))[0]
                if parent is None:
                    return RR(y)
            else:
                y = airy(complex(real(x), imag(x)))[0]
                if parent is None:
                    return CC(y)
            return parent(y)
        elif algorithm == 'mpmath':
            import mpmath
            from sage.libs.mpmath import utils as mpmath_utils
            return mpmath_utils.call(mpmath.airyai, x, parent=parent)
        else:
            raise ValueError("unknown algorithm '%s'" % algorithm)
 def __init__(self, parent, value, symbolic=None):
     FieldElement.__init__(
         self, parent)  ## this is so that canonical_coercion works.
     if not parent._mutable_values and value is not None:
         ## Test coercing the value to RR, so that we do not try to build a ParametricRealFieldElement
         ## from something like a tuple or vector or list or variable of a polynomial ring
         ## or something else that does not make any sense.
         # FIXME: parent(value) caused SIGSEGV because of an infinite recursion
         from sage.structure.coerce import py_scalar_parent
         if hasattr(value, 'parent'):
             if not RR.has_coerce_map_from(value.parent()):
                 raise TypeError("Value is of wrong type")
         else:
             if not RR.has_coerce_map_from(py_scalar_parent(type(value))):
                 raise TypeError("Value is of wrong type")
         self._val = value
     if symbolic is None:
         self._sym = value  # changed to not coerce into SR. -mkoeppe
     else:
         self._sym = symbolic
Exemplo n.º 17
0
    def _evalf_(self, x, **kwargs):
        """
        EXAMPLES::

            sage: airy_bi_prime(0.0)
            0.448288357353826

        We can use several methods for numerical evaluation::

            sage: airy_bi_prime(4).n(algorithm='mpmath')
            161.926683504613
            sage: airy_bi_prime(4).n(algorithm='mpmath', prec=100)
            161.92668350461340184309492429
            sage: airy_bi_prime(4).n(algorithm='scipy')  # rel tol 1e-10
            161.92668350461398
            sage: airy_bi_prime(I).n(algorithm='scipy')  # rel tol 1e-10
            0.135026646710819 - 0.1288373867812549*I

        TESTS::

            sage: parent(airy_bi_prime(3).n(algorithm='scipy'))
            Real Field with 53 bits of precision
            sage: airy_bi_prime(3).n(algorithm='scipy', prec=200)
            Traceback (most recent call last):
            ...
            NotImplementedError: airy_bi_prime not implemented
             for precision > 53
        """
        algorithm = kwargs.get('algorithm', 'mpmath') or 'mpmath'
        parent = kwargs.get('parent', None)
        if algorithm == 'scipy':
            if hasattr(parent, 'prec') and parent.prec() > 53:
                raise NotImplementedError("%s not implemented for precision > 53" % self.name())
            from sage.rings.real_mpfr import RR
            from sage.rings.cc import CC
            from sage.functions.other import real, imag
            from scipy.special import airy as airy
            if x in RR:
                y = airy(real(x))[3]
                if parent is None:
                    return RR(y)
            else:
                y = airy(complex(real(x), imag(x)))[3]
                if parent is None:
                    return CC(y)
            return parent(y)
        elif algorithm == 'mpmath':
            import mpmath
            from sage.libs.mpmath import utils as mpmath_utils
            return mpmath_utils.call(mpmath.airybi, x, derivative=1,
                                     parent=parent)
        else:
            raise ValueError("unknown algorithm '%s'" % algorithm)
Exemplo n.º 18
0
    def _evalf_(self, x, **kwargs):
        """
        EXAMPLES::

            sage: airy_ai_prime(0.0)
            -0.258819403792807

        We can use several methods for numerical evaluation::

            sage: airy_ai_prime(4).n(algorithm='mpmath')
            -0.00195864095020418
            sage: airy_ai_prime(4).n(algorithm='mpmath', prec=100)
            -0.0019586409502041789001381409184
            sage: airy_ai_prime(4).n(algorithm='scipy')    # rel tol 1e-10
            -0.00195864095020418
            sage: airy_ai_prime(I).n(algorithm='scipy')    # rel tol 1e-10
            -0.43249265984180707 + 0.09804785622924324*I

        TESTS::

            sage: parent(airy_ai_prime(3).n(algorithm='scipy'))
            Real Field with 53 bits of precision
            sage: airy_ai_prime(3).n(algorithm='scipy', prec=200)
            Traceback (most recent call last):
            ...
            NotImplementedError: airy_ai_prime not implemented
             for precision > 53
        """
        algorithm = kwargs.get('algorithm', 'mpmath') or 'mpmath'
        parent = kwargs.get('parent', None)
        if algorithm == 'scipy':
            if hasattr(parent, 'prec') and parent.prec() > 53:
                raise NotImplementedError("%s not implemented for precision > 53" % self.name())
            from sage.rings.real_mpfr import RR
            from sage.rings.cc import CC
            from sage.functions.other import real, imag
            from scipy.special import airy as airy
            if x in RR:
                y = airy(real(x))[1]
                if parent is None:
                    return RR(y)
            else:
                y = airy(complex(real(x), imag(x)))[1]
                if parent is None:
                    return CC(y)
            return parent(y)
        elif algorithm == 'mpmath':
            import mpmath
            from sage.libs.mpmath import utils as mpmath_utils
            return mpmath_utils.call(mpmath.airyai, x, derivative=1,
                                     parent=parent)
        else:
            raise ValueError("unknown algorithm '%s'" % algorithm)
 def __init__(self, parent, value, symbolic=None):
     FieldElement.__init__(
         self, parent)  ## this is so that canonical_coercion works.
     if not parent._mutable_values and value is not None:
         ## Test coercing the value to RR, so that we do not try to build a ParametricRealFieldElement
         ## from something like a tuple or vector or list or variable of a polynomial ring
         ## or something else that does not make any sense.
         from sage.interfaces.mathematica import MathematicaElement
         if not isinstance(value, MathematicaElement):
             RR(value)
         self._val = value
     if symbolic is None:
         self._sym = value  # changed to not coerce into SR. -mkoeppe
     else:
         self._sym = symbolic
Exemplo n.º 20
0
def perron_right_eigenvector(M):
    r"""
    EXAMPLES::

        sage: from slabbe.matrix_cocycle import perron_right_eigenvector
        sage: m = matrix(2,[-11,14,-26,29])
        sage: perron_right_eigenvector(m)           # tolerance 0.00001
        (15.0000000000000, (0.35, 0.6499999999999999))
    """
    from sage.modules.free_module_element import vector
    from sage.rings.real_mpfr import RR
    from sage.rings.all import CC
    import numpy
    eig, vec = numpy.linalg.eig(M)
    index = abs(eig).argmax()
    rightv = vec.transpose()[index]
    if eig[index].imag == 0:
        eig_sage = RR(eig[index].real)
        vec_sage = vector(a.real for a in rightv)
    else:
        eig_sage = CC(eig[index])
        vec_sage = vector(CC, rightv)
    return eig_sage, vec_sage/sum(vec_sage)
Exemplo n.º 21
0
def straight_line_plot(gs,
                       v,
                       directory="/tmp/",
                       pause_time=100,
                       width_in_inches=10,
                       file_offset=0):
    r"""
    Produces successively longer plots of a trajectory on the graphical surface gs which starts with the provided
    SimilaritySurfaceTangentVector, v. 
    
    The graphical surface gs is used to decide which segments to draw. Only segments drawn in visible
    polygons will be recorded.
    
    The directory given in the parameter will be filled with some data pertaining to the trajectory.
    A text file named orbit_setup.txt will be produced to record v. Periodically (after drawing pause_time 
    segments), the program will write to a text file, orbitN.txt about the segments and produce orbitN.svg 
    depicting the trajectory.
    
    The program will run until you press Control-C (or until your computer dies from an overheated processor :) ).

    EXAMPLE::
        
        from geometry.chamanara import GraphicalChamanaraSurface
        s=GraphicalChamanaraSurface(QQ(1)/2,8)
        
        from geometry.tangent_bundle import SimilaritySurfaceTangentBundle, SimilaritySurfaceTangentVector
        K.<sqrt2> = NumberField(x^2 - 2, embedding=AA(2).sqrt())
        tb = SimilaritySurfaceTangentBundle(s.get_surface())
        from sage.modules.free_module_element import vector
        v=SimilaritySurfaceTangentVector(tb, 0, vector((0,0)), vector((1,sqrt2)))
        
        from graphical.straight_line_plotter import straight_line_plot
        straight_line_plot(s,v, directory=".", pause_time = 100)
    """
    # Check the directory:
    from os import path
    if not path.isdir(directory):
        ValueError("Provided directory must be a directory")

    # Get a bounding box for the figure:
    xmin, ymin, xmax, ymax = gs.bounding_box()
    width = xmax - xmin
    height = ymax - ymin
    height_in_inches = height * width_in_inches / width
    figsize = [width_in_inches, height_in_inches]
    # Construct a segment using the tangent vector
    from geometry.straight_line_trajectory import SegmentInPolygon
    seg = SegmentInPolygon(v)

    # Used for drawing segments:
    from graphical.straight_line_trajectory import GraphicalSegmentInPolygon

    # Prepare to loop:
    all = 0
    count = 0

    # For providing human readable points
    from sage.rings.real_mpfr import RR

    # Record the initial conditions to a file:
    f = open(path.join(directory, "orbit_setup.txt"), 'w')
    f.write("v: " + str(v) + "\n")
    f.close()

    # Plot the surface
    from sage.plot.graphics import Graphics
    p = gs.plot()
    #p.save(path.join(directory,"orbit0.svg"),xmin=xmin,xmax=xmax,ymin=ymin,ymax=ymax, \
    #    figsize=figsize,axes=False,aspect_ratio=1,dpi=72)
    plot = p.matplotlib(xmin=xmin,
                        xmax=xmax,
                        ymin=ymin,
                        ymax=ymax,
                        axes=False,
                        aspect_ratio=1)
    plot.set_size_inches(figsize)
    plot.subplots_adjust(left=0, right=1, top=1, bottom=0)
    from matplotlib.backends.backend_agg import FigureCanvasAgg
    plot.set_canvas(FigureCanvasAgg(plot))
    plot.savefig(path.join(directory, "orbit0.svg"))

    #plot.savefig(path.join(directory,"orbit0.svg"),bbox_inches=0)
    p = Graphics()

    # Move forward through segments. Pay attention when the segment lies within our list of
    # polygons we care about. Plot them and print some data about them to a file.
    # Every 100 times we do this, we move to a new file.

    while True:
        filename_f = "orbit" + str(count / pause_time + file_offset) + ".txt"
        f = open(path.join(directory, filename_f), 'w')
        count_start = count
        while (count == count_start) or (count % pause_time != 0):
            if gs.is_visible(seg.polygon_label()):
                print("Segment #" + str(all) + " (plotted " + str(count) + ")")
                f.write("Segment #" + str(all) + " (plotted " + str(count) +
                        ")\n")
                f.write("Label: " + str(seg.polygon_label()) + "\n")
                f.write("point: " + str(seg.start_point()) + "\n")
                f.write("RR point: "+str(RR(seg.start_point()[0]))+", "+\
                    str(RR(seg.start_point()[1]))+"\n")
                gseg = GraphicalSegmentInPolygon(gs, seg)
                p += gseg.plot()
                count += 1
            # Move to next segment under flow:
            seg = seg.next()
            all += 1
        # Save the plot to a file.
        f.close()
        #p.save(path.join(directory,"orbit"+str(count/pause_time)+".svg"),xmin=xmin,xmax=xmax,ymin=ymin,ymax=ymax,fig_tight=True, \
        #    figsize=figsize,axes=False,aspect_ratio=1,transparent=True)

        plot = p.matplotlib(xmin=xmin,
                            xmax=xmax,
                            ymin=ymin,
                            ymax=ymax,
                            axes=False,
                            aspect_ratio=1)
        plot.set_size_inches(figsize)
        plot.subplots_adjust(left=0, right=1, top=1, bottom=0)
        from matplotlib.backends.backend_agg import FigureCanvasAgg
        plot.set_canvas(FigureCanvasAgg(plot))
        filename_p = "orbit" + str(count / pause_time + file_offset) + ".svg"
        plot.savefig(path.join(
            directory,
            "orbit" + str(count / pause_time + file_offset) + ".svg"),
                     transparent=True)

        # Write the pile file:
        filename_a = "orbit_pile" + str(count / pause_time +
                                        file_offset) + ".svg"
        a = open(path.join(directory, filename_a), 'w')
        a.write('<?xml version="1.0" encoding="utf-8" standalone="no"?>\n')
        a.write(
            '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"\n  "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\n'
        )
        a.write('<svg height="'+str(height_in_inches*72)+'pt" version="1.1" viewBox="0 0 '+ \
            str(width_in_inches*72)+' '+str(height_in_inches*72)+'" width="'+ \
            str(width_in_inches*72)+'pt" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">\n')
        for i in range(count / pause_time + 1 + file_offset):
            a.write('<image x="0" y="0" width="'+str(width_in_inches*72)+'" height="'+str(height_in_inches*72)+\
                '" xlink:href="orbit'+str(i)+'.svg" />\n')
        a.write('</svg>')
        a.close()

        p = Graphics()
        print("Wrote to files '" + filename_f + "', '" + filename_p +
              "' and '" + filename_a + "'.")
Exemplo n.º 22
0
    def dwt(self,other="haar",wavelet_k=2):
        """
        Wraps the gsl ``WaveletTransform.forward`` in :mod:`~sage.gsl.dwt`
        (written by Joshua Kantor). Assumes the length of the sample is a
        power of 2. Uses the GSL function ``gsl_wavelet_transform_forward()``.

        INPUT:

        - ``other`` -- the the name of the type of wavelet; valid choices are:

          * ``'daubechies'``
          * ``'daubechies_centered'``
          * ``'haar'`` (default)
          * ``'haar_centered'``
          * ``'bspline'``
          * ``'bspline_centered'``

        - ``wavelet_k`` -- For daubechies wavelets, ``wavelet_k`` specifies a
          daubechie wavelet with `k/2` vanishing moments.
          `k = 4,6,...,20` for `k` even are the only ones implemented.

          For Haar wavelets, ``wavelet_k`` must be 2.

          For bspline wavelets, ``wavelet_k`` equal to `103,105,202,204,
          206,208,301,305,307,309` will give biorthogonal B-spline wavelets
          of order `(i,j)` where ``wavelet_k`` equals `100 \cdot i + j`.

        The wavelet transform uses `J = \log_2(n)` levels.

        EXAMPLES::

            sage: J = range(8)
            sage: A = [RR(1) for i in J]
            sage: s = IndexedSequence(A,J)
            sage: t = s.dwt()
            sage: t        # slightly random output
            Indexed sequence: [2.82842712474999, 0.000000000000000, 0.000000000000000, 0.000000000000000, 0.000000000000000, 0.000000000000000, 0.000000000000000, 0.000000000000000]
                indexed by [0, 1, 2, 3, 4, 5, 6, 7]
        """
        # elements must be coercible into RR
        J = self.index_object()   ## must be = range(N)
        N = len(J)             ## must be 1 minus a power of 2
        S = self.list()
        if other == "haar" or other == "haar_centered":
            if wavelet_k in [2]:
                a = WaveletTransform(N,other,wavelet_k)
            else:
                raise ValueError("wavelet_k must be = 2")
        if other == "debauchies" or other == "debauchies_centered":
            if wavelet_k in [4,6,8,10,12,14,16,18,20]:
                a = WaveletTransform(N,other,wavelet_k)
            else:
                raise ValueError("wavelet_k must be in {4,6,8,10,12,14,16,18,20}")
        if other == "bspline" or other == "bspline_centered":
            if wavelet_k in [103,105,202,204,206,208,301,305,307,309]:
                a = WaveletTransform(N,other,103)
            else:
                raise ValueError("wavelet_k must be in {103,105,202,204,206,208,301,305,307,309}")
        for i in range(N):
            a[i] = S[i]
        a.forward_transform()
        return IndexedSequence([RR(a[j]) for j in J],J)
Exemplo n.º 23
0
    def points(self, **kwds):
        """
        Return some or all rational points of a projective scheme.

        For dimension 0 subschemes points are determined through a groebner
        basis calculation. For schemes or subschemes with dimension greater than 1
        points are determined through enumeration up to the specified bound.

        INPUT:

        kwds:

        - ``bound`` - real number (optional, default=0). The bound for the coordinates for
          subschemes with dimension at least 1.

        - ``precision`` - integer (optional, default=53). The precision to use to
          compute the elements of bounded height for number fields.

        - ``point_tolerance`` - positive real number (optional, default=10^(-10)).
          For numerically inexact fields, two points are considered the same
          if their coordinates are within tolerance.

        - ``zero_tolerance`` - positive real number (optional, default=10^(-10)).
          For numerically inexact fields, points are on the subscheme if they
          satisfy the equations to within tolerance.

        - ``tolerance`` - a rational number in (0,1] used in doyle-krumm algorithm-4
          for enumeration over number fields.

        OUTPUT:

        - a list of rational points of a projective scheme

        .. WARNING::
        
            For numerically inexact fields such as ComplexField or RealField the
            list of points returned is very likely to be incomplete. It may also
            contain repeated points due to tolerances.

        EXAMPLES::

            sage: P.<x,y> = ProjectiveSpace(QQ,1)
            sage: P(QQ).points(bound=4)
            [(-4 : 1), (-3 : 1), (-2 : 1), (-3/2 : 1), (-4/3 : 1), (-1 : 1),
            (-3/4 : 1), (-2/3 : 1), (-1/2 : 1), (-1/3 : 1), (-1/4 : 1), (0 : 1),
            (1/4 : 1), (1/3 : 1), (1/2 : 1), (2/3 : 1), (3/4 : 1), (1 : 0), (1 : 1),
            (4/3 : 1), (3/2 : 1), (2 : 1), (3 : 1), (4 : 1)]

        ::

            sage: u = QQ['u'].0
            sage: K.<v> = NumberField(u^2 + 3)
            sage: P.<x,y,z> = ProjectiveSpace(K,2)
            sage: len(P(K).points(bound=1.8))
            381

        ::

            sage: P1 = ProjectiveSpace(GF(2),1)
            sage: F.<a> = GF(4,'a')
            sage: P1(F).points()
            [(0 : 1), (1 : 0), (1 : 1), (a : 1), (a + 1 : 1)]

        ::

            sage: P.<x,y,z> = ProjectiveSpace(QQ,2)
            sage: E = P.subscheme([(y^3-y*z^2) - (x^3-x*z^2),(y^3-y*z^2) + (x^3-x*z^2)])
            sage: E(P.base_ring()).points()
            [(-1 : -1 : 1), (-1 : 0 : 1), (-1 : 1 : 1), (0 : -1 : 1), (0 : 0 : 1), (0 : 1 : 1),
            (1 : -1 : 1), (1 : 0 : 1), (1 : 1 : 1)]

        ::

            sage: P.<x,y,z> = ProjectiveSpace(CC, 2)
            sage: E = P.subscheme([y^3 - x^3 - x*z^2, x*y*z])
            sage: L=E(P.base_ring()).points(); sorted(L, key=str)
            verbose 0 (...: projective_homset.py, points) Warning: computations in the numerical fields are inexact;points may be computed partially or incorrectly.
            [(-0.500000000000000 + 0.866025403784439*I : 1.00000000000000 : 0.000000000000000),
            (-0.500000000000000 - 0.866025403784439*I : 1.00000000000000 : 0.000000000000000),
            (-1.00000000000000*I : 0.000000000000000 : 1.00000000000000),
            (0.000000000000000 : 0.000000000000000 : 1.00000000000000),
            (1.00000000000000 : 1.00000000000000 : 0.000000000000000),
            (1.00000000000000*I : 0.000000000000000 : 1.00000000000000)]
            sage: L[0].codomain()
            Projective Space of dimension 2 over Complex Field with 53 bits of precision

        ::

            sage: P.<x,y,z> = ProjectiveSpace(CDF, 2)
            sage: E = P.subscheme([y^2 + x^2 + z^2, x*y*z])
            sage: len(E(P.base_ring()).points())
            verbose 0 (...: projective_homset.py, points) Warning: computations in the numerical fields are inexact;points may be computed partially or incorrectly.
            6
        """
        from sage.schemes.projective.projective_space import is_ProjectiveSpace
        X = self.codomain()
        if not is_ProjectiveSpace(X) and X.base_ring() in Fields():
            if hasattr(X.base_ring(), 'precision'):
                numerical = True
                verbose(
                    "Warning: computations in the numerical fields are inexact;points may be computed partially or incorrectly.",
                    level=0)
                pt_tol = RR(kwds.pop('point_tolerance', 10**(-10)))
                zero_tol = RR(kwds.pop('zero_tolerance', 10**(-10)))
                if pt_tol <= 0 or zero_tol <= 0:
                    raise ValueError("tolerance must be positive")
            else:
                numerical = False
            #Then it must be a subscheme
            dim_ideal = X.defining_ideal().dimension()
            if dim_ideal < 1:  # no points
                return []
            if dim_ideal == 1:  # if X zero-dimensional
                rat_points = set()
                PS = X.ambient_space()
                N = PS.dimension_relative()
                BR = X.base_ring()
                #need a lexicographic ordering for elimination
                R = PolynomialRing(BR, N + 1, PS.variable_names(), order='lex')
                I = R.ideal(X.defining_polynomials())
                I0 = R.ideal(0)
                #Determine the points through elimination
                #This is much faster than using the I.variety() function on each affine chart.
                for k in range(N + 1):
                    #create the elimination ideal for the kth affine patch
                    G = I.substitute({R.gen(k): 1}).groebner_basis()
                    if G != [1]:
                        P = {}
                        #keep track that we know the kth coordinate is 1
                        P.update({R.gen(k): 1})
                        points = [P]
                        #work backwards from solving each equation for the possible
                        #values of the next coordinate
                        for i in range(len(G) - 1, -1, -1):
                            new_points = []
                            good = 0
                            for P in points:
                                #substitute in our dictionary entry that has the values
                                #of coordinates known so far. This results in a single
                                #variable polynomial (by elimination)
                                L = G[i].substitute(P)
                                if R(L).degree() > 0:
                                    if numerical:
                                        for pol in L.univariate_polynomial(
                                        ).roots(multiplicities=False):
                                            good = 1
                                            r = L.variables()[0]
                                            varindex = R.gens().index(r)
                                            P.update({R.gen(varindex): pol})
                                            new_points.append(copy(P))
                                    else:
                                        L = L.factor()
                                        #the linear factors give the possible rational values of
                                        #this coordinate
                                        for pol, pow in L:
                                            if pol.degree() == 1 and len(
                                                    pol.variables()) == 1:
                                                good = 1
                                                r = pol.variables()[0]
                                                varindex = R.gens().index(r)
                                                #add this coordinates information to
                                                #each dictionary entry
                                                P.update({
                                                    R.gen(varindex):
                                                    -pol.constant_coefficient(
                                                    ) /
                                                    pol.monomial_coefficient(r)
                                                })
                                                new_points.append(copy(P))
                                else:
                                    new_points.append(P)
                                    good = 1
                            if good:
                                points = new_points
                        #the dictionary entries now have values for all coordinates
                        #they are the rational solutions to the equations
                        #make them into projective points
                        for i in range(len(points)):
                            if numerical:
                                if len(points[i]) == N + 1:
                                    S = PS([
                                        points[i][R.gen(j)]
                                        for j in range(N + 1)
                                    ])
                                    S.normalize_coordinates()
                                    if all(
                                            g(list(S)) < zero_tol
                                            for g in X.defining_polynomials()):
                                        rat_points.add(S)
                            else:
                                if len(points[i]) == N + 1 and I.subs(
                                        points[i]) == I0:
                                    S = X([
                                        points[i][R.gen(j)]
                                        for j in range(N + 1)
                                    ])
                                    S.normalize_coordinates()
                                    rat_points.add(S)

                # remove duplicate element using tolerance
                if numerical:
                    dupl_points = list(rat_points)
                    for i in range(len(dupl_points)):
                        u = dupl_points[i]
                        for j in range(i + 1, len(dupl_points)):
                            v = dupl_points[j]
                            if all((u[k] - v[k]).abs() < pt_tol
                                   for k in range(len(u))):
                                rat_points.remove(u)
                                break

                rat_points = sorted(rat_points)
                return rat_points
        R = self.value_ring()
        B = kwds.pop('bound', 0)
        tol = kwds.pop('tolerance', 1e-2)
        prec = kwds.pop('precision', 53)
        if is_RationalField(R):
            if not B > 0:
                raise TypeError("a positive bound B (= %s) must be specified" %
                                B)
            if isinstance(X, AlgebraicScheme_subscheme
                          ):  # sieve should only be called for subschemes
                from sage.schemes.projective.projective_rational_point import sieve
                return sieve(X, B)
            else:
                from sage.schemes.projective.projective_rational_point import enum_projective_rational_field
                return enum_projective_rational_field(self, B)
        elif R in NumberFields():
            if not B > 0:
                raise TypeError("a positive bound B (= %s) must be specified" %
                                B)
            from sage.schemes.projective.projective_rational_point import enum_projective_number_field
            return enum_projective_number_field(self,
                                                bound=B,
                                                tolerance=tol,
                                                precision=prec)
        elif is_FiniteField(R):
            from sage.schemes.projective.projective_rational_point import enum_projective_finite_field
            return enum_projective_finite_field(self.extended_codomain())
        else:
            raise TypeError("unable to enumerate points over %s" % R)
Exemplo n.º 24
0
    def numerical_points(self, F=None, **kwds):
        """
        Return some or all numerical approximations of rational points of a projective scheme.

        This is for dimension 0 subschemes only and the points are determined
        through a groebner calculation over the base ring and then numerically
        approximating the roots of the resulting polynomials. If the base ring
        is a number field, the embedding into ``F`` must be known.

        INPUT:

        ``F`` - numerical ring

        kwds:

        - ``point_tolerance`` - positive real number (optional, default=10^(-10)).
          For numerically inexact fields, two points are considered the same
          if their coordinates are within tolerance.

        - ``zero_tolerance`` - positive real number (optional, default=10^(-10)).
          For numerically inexact fields, points are on the subscheme if they
          satisfy the equations to within tolerance.

        OUTPUT: A list of points in the ambient space.

        .. WARNING::

           For numerically inexact fields the list of points returned may contain repeated
           or be missing points due to tolerance.

        EXAMPLES::

            sage: P.<x,y,z> = ProjectiveSpace(QQ, 2)
            sage: E = P.subscheme([y^3 - x^3 - x*z^2, x*y*z])
            sage: L = E(QQ).numerical_points(F=RR); L
            [(0.000000000000000 : 0.000000000000000 : 1.00000000000000),
             (1.00000000000000 : 1.00000000000000 : 0.000000000000000)]
            sage: L[0].codomain()
            Projective Space of dimension 2 over Real Field with 53 bits of precision

        ::

            sage: S.<a> = QQ[]
            sage: K.<v> = NumberField(a^5 - 7, embedding=CC((7)**(1/5)))
            sage: P.<x,y,z> = ProjectiveSpace(K,2)
            sage: X = P.subscheme([x^2 - v^2*z^2, y-v*z])
            sage: len(X(K).numerical_points(F=CDF))
            2

        ::

            sage: P.<x1, x2, x3> = ProjectiveSpace(QQ, 2)
            sage: E = P.subscheme([3000*x1^50 + 9875643*x2^2*x3^48 + 12334545*x2^50, x1 + x2])
            sage: len(E(P.base_ring()).numerical_points(F=CDF, zero_tolerance=1e-6))
            49

        TESTS::

            sage: P.<x,y,z> = ProjectiveSpace(QQ, 2)
            sage: E = P.subscheme([y^3 - x^3 - x*z^2, x*y*z])
            sage: E(QQ).numerical_points(F=CDF, point_tolerance=-1)
            Traceback (most recent call last):
            ...
            ValueError: tolerance must be positive

        ::

            sage: P.<x,y,z> = ProjectiveSpace(QQ, 2)
            sage: E = P.subscheme([y^3 - x^3 - x*z^2, x*y*z])
            sage: E(QQ).numerical_points(F=CC, zero_tolerance=-1)
            Traceback (most recent call last):
            ...
            ValueError: tolerance must be positive

        ::

            sage: P.<x,y,z> = ProjectiveSpace(QQ, 2)
            sage: E = P.subscheme([y^3 - x^3 - x*z^2, x*y*z])
            sage: E(QQ).numerical_points(F=QQbar)
            Traceback (most recent call last):
            ...
            TypeError: F must be a numerical field
        """
        from sage.schemes.projective.projective_space import is_ProjectiveSpace
        if F is None:
            F = CC
        if F not in Fields() or not hasattr(F, 'precision'):
            raise TypeError('F must be a numerical field')
        X = self.codomain()
        if X.base_ring() not in NumberFields():
            raise TypeError('base ring must be a number field')

        PP = X.ambient_space().change_ring(F)
        if not is_ProjectiveSpace(X) and X.base_ring() in Fields():
            #Then it must be a subscheme
            dim_ideal = X.defining_ideal().dimension()
            if dim_ideal < 1:  # no points
                return []
            if dim_ideal == 1:  # if X zero-dimensional
                pt_tol = RR(kwds.pop('point_tolerance', 10**(-10)))
                zero_tol = RR(kwds.pop('zero_tolerance', 10**(-10)))
                if pt_tol <= 0 or zero_tol <= 0:
                    raise ValueError("tolerance must be positive")
                rat_points = set()
                PS = X.ambient_space()
                N = PS.dimension_relative()
                BR = X.base_ring()
                #need a lexicographic ordering for elimination
                R = PolynomialRing(BR, N + 1, PS.variable_names(), order='lex')
                RF = R.change_ring(F)
                I = R.ideal(X.defining_polynomials())
                #Determine the points through elimination
                #This is much faster than using the I.variety() function on each affine chart.
                for k in range(N + 1):
                    #create the elimination ideal for the kth affine patch
                    G = I.substitute({R.gen(k): 1}).groebner_basis()
                    G = [RF(g) for g in G]
                    if G != [1]:
                        P = {}
                        #keep track that we know the kth coordinate is 1
                        P.update({RF.gen(k): 1})
                        points = [P]
                        #work backwards from solving each equation for the possible
                        #values of the next coordinate
                        for i in range(len(G) - 1, -1, -1):
                            new_points = []
                            good = 0
                            for P in points:
                                #substitute in our dictionary entry that has the values
                                #of coordinates known so far. This results in a single
                                #variable polynomial (by elimination)
                                L = G[i].substitute(P)
                                if len(RF(L).variables()) == 1:
                                    for pol in L.univariate_polynomial().roots(
                                            ring=F, multiplicities=False):
                                        r = L.variables()[0]
                                        varindex = RF.gens().index(r)
                                        P.update({RF.gen(varindex): pol})
                                        new_points.append(copy(P))
                                        good = 1
                                else:
                                    new_points.append(P)
                                    good = 1
                            if good:
                                points = new_points
                        #the dictionary entries now have values for all coordinates
                        #they are approximate solutions to the equations
                        #make them into projective points
                        polys = [
                            g.change_ring(F) for g in X.defining_polynomials()
                        ]
                        for i in range(len(points)):
                            if len(points[i]) == N + 1:
                                S = PP([
                                    points[i][RF.gen(j)] for j in range(N + 1)
                                ])
                                S.normalize_coordinates()
                                if all(g(list(S)) < zero_tol for g in polys):
                                    rat_points.add(S)
                        # remove duplicate element using tolerance
                        #since they are normalized we can just compare coefficients
                        dupl_points = list(rat_points)
                        for i in range(len(dupl_points)):
                            u = dupl_points[i]
                            for j in range(i + 1, len(dupl_points)):
                                v = dupl_points[j]
                                if all((u[k] - v[k]).abs() < pt_tol
                                       for k in range(len(u))):
                                    rat_points.remove(u)
                                    break

                rat_points = sorted(rat_points)
                return rat_points
            raise NotImplementedError(
                'numerical approximation of points only for dimension 0 subschemes'
            )
Exemplo n.º 25
0
    def points(self, **kwds):
        r"""
        Return some or all rational points of an affine scheme.

        For dimension 0 subschemes points are determined through a groebner
        basis calculation. For schemes or subschemes with dimension greater than 1
        points are determined through enumeration up to the specified bound.

        Over a finite field, all points are returned. Over an infinite field, all points satisfying the bound
        are returned. For a zero-dimensional subscheme, all points are returned regardless of whether the field
        is infinite or not.

        For number fields, this uses the
        Doyle-Krumm algorithm 4 (algorithm 5 for imaginary quadratic) for
        computing algebraic numbers up to a given height [DK2013]_.

        The algorithm requires floating point arithmetic, so the user is
        allowed to specify the precision for such calculations.
        Additionally, due to floating point issues, points
        slightly larger than the bound may be returned. This can be controlled
        by lowering the tolerance.


        INPUT:

        kwds:

        - ``bound`` - real number (optional, default: 0). The bound for the
          height of the coordinates. Only used for subschemes with
          dimension at least 1.

        - ``zero_tolerance`` - positive real number (optional, default=10^(-10)).
          For numerically inexact fields, points are on the subscheme if they
          satisfy the equations to within tolerance.

        - ``tolerance`` - a rational number in (0,1] used in doyle-krumm algorithm-4
          for enumeration over number fields.

        - ``precision`` - the precision to use for computing the elements of
          bounded height of number fields.

        OUTPUT:

        - a list of rational points of a affine scheme

        .. WARNING::

           For numerically inexact fields such as ComplexField or RealField the
           list of points returned is very likely to be incomplete. It may also
           contain repeated points due to tolerance.

        EXAMPLES: The bug reported at #11526 is fixed::

            sage: A2 = AffineSpace(ZZ, 2)
            sage: F = GF(3)
            sage: A2(F).points()
            [(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2)]

        ::

            sage: A.<x,y> = ZZ[]
            sage: I = A.ideal(x^2-y^2-1)
            sage: V = AffineSpace(ZZ, 2)
            sage: X = V.subscheme(I)
            sage: M = X(ZZ)
            sage: M.points(bound=1)
            [(-1, 0), (1, 0)]

        ::

            sage: u = QQ['u'].0
            sage: K.<v> = NumberField(u^2 + 3)
            sage: A.<x,y> = AffineSpace(K, 2)
            sage: len(A(K).points(bound=2))
            1849

        ::

            sage: A.<x,y> = AffineSpace(QQ, 2)
            sage: E = A.subscheme([x^2 + y^2 - 1, y^2 - x^3 + x^2 + x - 1])
            sage: E(A.base_ring()).points()
            [(-1, 0), (0, -1), (0, 1), (1, 0)]

        ::

            sage: A.<x,y> = AffineSpace(CC, 2)
            sage: E = A.subscheme([y^3 - x^3 - x^2, x*y])
            sage: E(A.base_ring()).points()
            verbose 0 (...: affine_homset.py, points) Warning: computations in the numerical fields are inexact;points may be computed partially or incorrectly.
            [(-1.00000000000000, 0.000000000000000),
            (0.000000000000000, 0.000000000000000)]

        ::

            sage: A.<x1,x2> = AffineSpace(CDF, 2)
            sage: E = A.subscheme([x1^2 + x2^2 + x1*x2, x1 + x2])
            sage: E(A.base_ring()).points()
            verbose 0 (...: affine_homset.py, points) Warning: computations in the numerical fields are inexact;points may be computed partially or incorrectly.
            [(0.0, 0.0)]
        """
        from sage.schemes.affine.affine_space import is_AffineSpace

        X = self.codomain()
        if not is_AffineSpace(X) and X.base_ring() in Fields():
            if hasattr(X.base_ring(), 'precision'):
                numerical = True
                verbose(
                    "Warning: computations in the numerical fields are inexact;points may be computed partially or incorrectly.",
                    level=0)
                zero_tol = RR(kwds.pop('zero_tolerance', 10**(-10)))
                if zero_tol <= 0:
                    raise ValueError("tolerance must be positive")
            else:
                numerical = False
            # Then X must be a subscheme
            dim_ideal = X.defining_ideal().dimension()
            if dim_ideal < 0:  # no points
                return []
            if dim_ideal == 0:  # if X zero-dimensional
                rat_points = []
                AS = X.ambient_space()
                N = AS.dimension_relative()
                BR = X.base_ring()
                #need a lexicographic ordering for elimination
                R = PolynomialRing(BR, N, AS.gens(), order='lex')
                I = R.ideal(X.defining_polynomials())
                I0 = R.ideal(0)
                #Determine the points through elimination
                #This is much faster than using the I.variety() function on each affine chart.
                G = I.groebner_basis()
                if G != [1]:
                    P = {}
                    points = [P]
                    #work backwards from solving each equation for the possible
                    #values of the next coordinate
                    for i in range(len(G) - 1, -1, -1):
                        new_points = []
                        good = 0
                        for P in points:
                            #substitute in our dictionary entry that has the values
                            #of coordinates known so far. This results in a single
                            #variable polynomial (by elimination)
                            L = G[i].substitute(P)
                            if R(L).degree() > 0:
                                if numerical:
                                    for pol in L.univariate_polynomial().roots(
                                            multiplicities=False):
                                        r = L.variables()[0]
                                        varindex = R.gens().index(r)
                                        P.update({R.gen(varindex): pol})
                                        new_points.append(copy(P))
                                        good = 1
                                else:
                                    L = L.factor()
                                    #the linear factors give the possible rational values of
                                    #this coordinate
                                    for pol, pow in L:
                                        if pol.degree() == 1 and len(
                                                pol.variables()) == 1:
                                            good = 1
                                            r = pol.variables()[0]
                                            varindex = R.gens().index(r)
                                            #add this coordinates information to
                                            #each dictionary entry
                                            P.update({
                                                R.gen(varindex):
                                                -pol.constant_coefficient() /
                                                pol.monomial_coefficient(r)
                                            })
                                            new_points.append(copy(P))
                            else:
                                new_points.append(P)
                                good = 1
                        if good:
                            points = new_points
                    #the dictionary entries now have values for all coordinates
                    #they are the rational solutions to the equations
                    #make them into affine points
                    for i in range(len(points)):
                        if numerical:
                            if len(points[i]) == N:
                                S = AS([points[i][R.gen(j)] for j in range(N)])
                                if all(
                                        g(list(S)) < zero_tol
                                        for g in X.defining_polynomials()):
                                    rat_points.append(S)
                        else:
                            if len(points[i]) == N and I.subs(points[i]) == I0:
                                S = X([points[i][R.gen(j)] for j in range(N)])
                                rat_points.append(S)

                rat_points = sorted(rat_points)
                return rat_points
        R = self.value_ring()
        B = kwds.pop('bound', 0)
        tol = kwds.pop('tolerance', 1e-2)
        prec = kwds.pop('precision', 53)
        if is_RationalField(R) or R == ZZ:
            if not B > 0:
                raise TypeError("a positive bound B (= %s) must be specified" %
                                B)
            from sage.schemes.affine.affine_rational_point import enum_affine_rational_field
            return enum_affine_rational_field(self, B)
        if R in NumberFields():
            if not B > 0:
                raise TypeError("a positive bound B (= %s) must be specified" %
                                B)
            from sage.schemes.affine.affine_rational_point import enum_affine_number_field
            return enum_affine_number_field(self,
                                            bound=B,
                                            tolerance=tol,
                                            precision=prec)
        elif is_FiniteField(R):
            from sage.schemes.affine.affine_rational_point import enum_affine_finite_field
            return enum_affine_finite_field(self)
        else:
            raise TypeError("unable to enumerate points over %s" % R)
Exemplo n.º 26
0
def mega_plot(K, x, y, dx, dy, directory="/tmp/", pause_time=100):
    r"""
    Plots a trajectory on the MegaWollmilchsau which starts at (x,y) in the square and
    moves in direction of the vector (dx,dy). It only plots within three squares
    surrounding the base square. 
    
    The directory given in the parameter will be filled with some data pertaining to the trajectory.
    A text file named orbit_setup.txt will be produced to describe the initial conditions.
    Periodically (after drawing pause_time segments), the program will write to a text file
    orbitN.txt about the segments and produce orbitN.svg depicting the trajectory.
    
    The program will run until you press Control-C (or until the power is cut to your processor :) ).

        sage: import flatsurf
        sage: import flatsurf.demo
        sage: from flatsurf.demo.mega_wollmilchsau_plotter import mega_plot
        sage: from sage.calculus.predefined import x
        sage: from sage.rings.integer_ring import ZZ
        sage: from sage.rings.number_field.number_field import NumberField
        sage: K.<sqrt2> = NumberField(x**2-2, embedding=ZZ(1))
        sage: x = K.zero()
        sage: y = K.zero()
        sage: dx = K.one()
        sage: dy = sqrt2
        sage: mega_plot(K,x,y,dx,dy, directory="/tmp/", pause_time = 10)  # not tested: BUG
        Segment #0 (plotted 0)
        Segment #1 (plotted 1)...
    """
    # Check the directory:
    from os import path
    if not path.isdir(directory):
        ValueError("Provided directory must be a directory")

    # Construct the surface:
    from flatsurf.geometry.mega_wollmilchsau import MegaWollmilchsau
    s = MegaWollmilchsau()

    # Get the labels for 3 polygons.
    l0 = s.base_label()
    l1 = s.opposite_edge(l0, 1)[0]
    l2 = s.opposite_edge(l0, 2)[0]
    labels = [l0, l1, l2]

    # Setup the portion of the surface we want to draw
    from flatsurf.graphical.surface import GraphicalSurface
    gs = GraphicalSurface(s)
    gs.make_adjacent_and_visible(l0, 1)
    gs.make_adjacent_and_visible(l0, 2)

    # Construct a tangent vector
    from flatsurf.geometry.tangent_bundle import SimilaritySurfaceTangentBundle, SimilaritySurfaceTangentVector
    tb = SimilaritySurfaceTangentBundle(s)
    from sage.modules.free_module import VectorSpace
    V = VectorSpace(K, 2)
    v = SimilaritySurfaceTangentVector(tb, l0, V((x, y)), V((dx, dy)))

    # Construct a segment using the tangent vector
    from flatsurf.geometry.straight_line_trajectory import SegmentInPolygon
    seg = SegmentInPolygon(v)

    # Plot the surface
    p = gs.plot()

    # Used for drawing segments:
    from flatsurf.graphical.straight_line_trajectory import GraphicalSegmentInPolygon

    # Prepare to loop:
    all = 0
    count = 0

    # For providing human readable points
    from sage.rings.real_mpfr import RR

    # Record the initial conditions to a file:
    f = open(path.join(directory, "orbit_setup.txt"), 'w')
    f.write("Field: " + str(K) + "\n")
    f.write("x: " + str(x) + "\n")
    f.write("y: " + str(y) + "\n")
    f.write("dx: " + str(dx) + "\n")
    f.write("dy: " + str(dy) + "\n")
    f.close()

    # Move forward through segments. Pay attention when the segment lies within our list of
    # polygons we care about. Plot them and print some data about them to a file.
    # Every 100 times we do this, we move to a new file.

    while True:
        f = open(
            path.join(directory, "orbit" + str(count / pause_time) + ".txt"),
            'w')
        count_start = count
        while (count == count_start) or (count % pause_time != 0):
            if seg.polygon_label() in labels:
                print("Segment #" + str(all) + " (plotted " + str(count) + ")")
                f.write("Segment #" + str(all) + " (plotted " + str(count) +
                        ")\n")
                f.write("Label: " + str(seg.polygon_label()) + "\n")
                f.write("point: " + str(seg.start_point()) + "\n")
                f.write("RR point: "+str(RR(seg.start_point()[0]))+", "+\
                    str(RR(seg.start_point()[1]))+"\n")
                gseg = GraphicalSegmentInPolygon(gs, seg)
                p += gseg.plot()
                count += 1
            # Move to next segment under flow:
            seg = seg.next()
            all += 1
        # Save the plot to a file.
        f.close()
        p.save(
            path.join(directory,
                      "orbit" + str(count / pause_time - 1) + ".svg"))
        print("Wrote to files named 'orbit" + str(count / pause_time - 1) +
              "' with extension .txt and .svg")
Exemplo n.º 27
0
    def idwt(self, other="haar", wavelet_k=2):
        """
        Implements the gsl ``WaveletTransform.backward()`` in
        :mod:`~sage.gsl.dwt`.

        Assumes the length of the sample is a power of 2. Uses the
        GSL function ``gsl_wavelet_transform_backward()``.

        INPUT:

        - ``other`` -- Must be one of the following:

          * ``"haar"``
          * ``"daubechies"``
          * ``"daubechies_centered"``
          * ``"haar_centered"``
          * ``"bspline"``
          * ``"bspline_centered"``

        - ``wavelet_k`` -- For daubechies wavelets, ``wavelet_k`` specifies a
          daubechie wavelet with `k/2` vanishing moments.
          `k = 4,6,...,20` for `k` even are the only ones implemented.

          For Haar wavelets, ``wavelet_k`` must be 2.

          For bspline wavelets, ``wavelet_k`` equal to `103,105,202,204,
          206,208,301,305,307,309` will give biorthogonal B-spline wavelets
          of order `(i,j)` where ``wavelet_k`` equals `100 \cdot i + j`.

        EXAMPLES::

            sage: J = range(8)
            sage: A = [RR(1) for i in J]
            sage: s = IndexedSequence(A,J)
            sage: t = s.dwt()
            sage: t            # random arch dependent output
            Indexed sequence: [2.82842712474999, 0.000000000000000, 0.000000000000000, 0.000000000000000, 0.000000000000000, 0.000000000000000, 0.000000000000000, 0.000000000000000]
                indexed by [0, 1, 2, 3, 4, 5, 6, 7]
            sage: t.idwt()                  # random arch dependent output
            Indexed sequence: [1.00000000000000, 1.00000000000000, 1.00000000000000, 1.00000000000000, 1.00000000000000, 1.00000000000000, 1.00000000000000, 1.00000000000000]
                indexed by [0, 1, 2, 3, 4, 5, 6, 7]
            sage: t.idwt() == s
            True
            sage: J = range(16)
            sage: A = [RR(1) for i in J]
            sage: s = IndexedSequence(A,J)
            sage: t = s.dwt("bspline", 103)
            sage: t   # random arch dependent output
            Indexed sequence: [4.00000000000000, 0.000000000000000, 0.000000000000000, 0.000000000000000, 0.000000000000000, 0.000000000000000, 0.000000000000000, 0.000000000000000, 0.000000000000000, 0.000000000000000, 0.000000000000000, 0.000000000000000, 0.000000000000000, 0.000000000000000, 0.000000000000000, 0.000000000000000]
                indexed by [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
            sage: t.idwt("bspline", 103) == s
            True
        """
        # elements must be coercible into RR
        J = self.index_object()   ## must be = range(N)
        N = len(J)             ## must be 1 minus a power of 2
        S = self.list()
        k = wavelet_k
        if other=="haar" or other=="haar_centered":
            if k in [2]:
                a = WaveletTransform(N,other,wavelet_k)
            else:
                raise ValueError("wavelet_k must be = 2")
        if other=="debauchies" or other=="debauchies_centered":
            if k in [4,6,8,10,12,14,16,18,20]:
                a = WaveletTransform(N,other,wavelet_k)
            else:
                raise ValueError("wavelet_k must be in {4,6,8,10,12,14,16,18,20}")
        if other=="bspline" or other=="bspline_centered":
            if k in [103,105,202,204,206,208,301,305,307,309]:
                a = WaveletTransform(N,other,103)
            else:
                raise ValueError("wavelet_k must be in {103,105,202,204,206,208,301,305,307,309}")
        for i in range(N):
            a[i] = S[i]
        a.backward_transform()
        return IndexedSequence([RR(a[j]) for j in J],J)
Exemplo n.º 28
0
    def numerical_points(self, F=None, **kwds):
        """
        Return some or all numerical approximations of rational points of an affine scheme.

        This is for dimension 0 subschemes only and the points are determined
        through a groebner calculation over the base ring and then numerically
        approximating the roots of the resulting polynomials. If the base ring
        is a number field, the embedding into ``F`` must be known.

        INPUT:

        ``F`` - numerical ring

        kwds:

        - ``zero_tolerance`` - positive real number (optional, default=10^(-10)).
          For numerically inexact fields, points are on the subscheme if they
          satisfy the equations to within tolerance.

        OUTPUT: A list of points in the ambient space.

        .. WARNING::

           For numerically inexact fields the list of points returned may contain repeated
           or be missing points due to tolerance.

        EXAMPLES::

            sage: K.<v> = QuadraticField(3)
            sage: A.<x,y> = AffineSpace(K, 2)
            sage: X = A.subscheme([x^3 - v^2*y, y - v*x^2 + 3])
            sage: L = X(K).numerical_points(F=RR); L  # abs tol 1e-14
            [(-1.18738247880014, -0.558021142104134),
             (1.57693558184861, 1.30713548084184),
             (4.80659931965815, 37.0162574656220)]
            sage: L[0].codomain()
            Affine Space of dimension 2 over Real Field with 53 bits of precision

        ::

            sage: A.<x,y> = AffineSpace(QQ, 2)
            sage: X = A.subscheme([y^2 - x^2 - 3*x, x^2 - 10*y])
            sage: len(X(QQ).numerical_points(F=ComplexField(100)))
            4

        ::

            sage: A.<x1, x2> = AffineSpace(QQ, 2)
            sage: E = A.subscheme([30*x1^100 + 1000*x2^2 + 2000*x1*x2 + 1, x1 + x2])
            sage: len(E(A.base_ring()).numerical_points(F=CDF, zero_tolerance=1e-9))
            100

        TESTS::

            sage: A.<x,y> = AffineSpace(QQ, 2)
            sage: X = A.subscheme([y^2 - x^2 - 3*x, x^2 - 10*y])
            sage: X(QQ).numerical_points(F=QQ)
            Traceback (most recent call last):
            ...
            TypeError: F must be a numerical field

        ::

            sage: A.<x,y> = AffineSpace(QQ, 2)
            sage: X = A.subscheme([y^2 - x^2 - 3*x, x^2 - 10*y])
            sage: X(QQ).numerical_points(F=CC, zero_tolerance=-1)
            Traceback (most recent call last):
            ...
            ValueError: tolerance must be positive
        """
        from sage.schemes.affine.affine_space import is_AffineSpace
        if F is None:
            F = CC
        if F not in Fields() or not hasattr(F, 'precision'):
            raise TypeError('F must be a numerical field')
        X = self.codomain()
        if X.base_ring() not in NumberFields():
            raise TypeError('base ring must be a number field')

        AA = X.ambient_space().change_ring(F)
        if not is_AffineSpace(X) and X.base_ring() in Fields():
            # Then X must be a subscheme
            dim_ideal = X.defining_ideal().dimension()
            if dim_ideal != 0:  # no points
                return []
        else:
            return []

        # if X zero-dimensional
        zero_tol = RR(kwds.pop('zero_tolerance', 10**(-10)))
        if zero_tol <= 0:
            raise ValueError("tolerance must be positive")
        rat_points = []
        PS = X.ambient_space()
        N = PS.dimension_relative()
        BR = X.base_ring()
        # need a lexicographic ordering for elimination
        R = PolynomialRing(BR, N, PS.gens(), order='lex')
        RF = R.change_ring(F)
        I = R.ideal(X.defining_polynomials())
        # Determine the points through elimination This is much faster
        # than using the I.variety() function on each affine chart.
        G = I.groebner_basis()
        G = [RF(g) for g in G]
        if G != [1]:
            P = {}
            points = [P]
            # work backwards from solving each equation for the possible
            # values of the next coordinate
            for g in reversed(G):
                new_points = []
                good = False
                for P in points:
                    # substitute in our dictionary entry that has the
                    # values of coordinates known so far. This results
                    # in a single variable polynomial (by elimination)
                    L = g.substitute(P)
                    if len(RF(L).variables()) == 1:
                        r = L.variables()[0]
                        var = RF.gen(RF.gens().index(r))

                        for pol in L.univariate_polynomial().roots(
                                ring=F, multiplicities=False):
                            P[var] = pol
                            new_points.append(copy(P))
                            good = True
                    else:
                        new_points.append(P)
                        good = True
                if good:
                    points = new_points
            # the dictionary entries now have values for all
            # coordinates they are the rational solutions to the
            # equations make them into affine points
            polys = [g.change_ring(F) for g in X.defining_polynomials()]
            for P in points:
                if len(P) == N:
                    S = AA([P[R.gen(j)] for j in range(N)])
                    if all(g(list(S)) < zero_tol for g in polys):
                        rat_points.append(S)

        rat_points = sorted(rat_points)
        return rat_points
Exemplo n.º 29
0
def det_given_divisor(A, d, proof=True, stabilize=2):
    """
    Given a divisor d of the determinant of A, compute the determinant of A.

    INPUT:

    - ``A`` -- a square integer matrix
    - ``d`` -- a nonzero integer that is assumed to divide the determinant of A
    - ``proof`` -- bool (default: True) compute det modulo enough primes
      so that the determinant is computed provably correctly (via the
      Hadamard bound).  It would be VERY hard for ``det()`` to fail even
      with proof=False.
    - ``stabilize`` -- int (default: 2) if proof = False, then compute
      the determinant modulo `p` until ``stabilize`` successive modulo
      determinant computations stabilize.

    OUTPUT:

    integer -- determinant

    EXAMPLES::

        sage: import sage.matrix.matrix_integer_dense_hnf as matrix_integer_dense_hnf
        sage: a = matrix(ZZ,3,[-1, -1, -1, -20, 4, 1, -1, 1, 2])
        sage: matrix_integer_dense_hnf.det_given_divisor(a, 3)
        -30
        sage: matrix_integer_dense_hnf.det_given_divisor(a, 3, proof=False)
        -30
        sage: matrix_integer_dense_hnf.det_given_divisor(a, 3, proof=False, stabilize=1)
        -30
        sage: a.det()
        -30

    Here we illustrate proof=False giving a wrong answer::

        sage: p = matrix_integer_dense_hnf.max_det_prime(2)
        sage: q = previous_prime(p)
        sage: a = matrix(ZZ, 2, [p, 0, 0, q])
        sage: p * q
        70368442188091
        sage: matrix_integer_dense_hnf.det_given_divisor(a, 1, proof=False, stabilize=2)
        0

    This still works, because we do not work modulo primes that divide
    the determinant bound, which is found using a p-adic algorithm::

        sage: a.det(proof=False, stabilize=2)
        70368442188091

    3 primes is enough::

        sage: matrix_integer_dense_hnf.det_given_divisor(a, 1, proof=False, stabilize=3)
        70368442188091
        sage: matrix_integer_dense_hnf.det_given_divisor(a, 1, proof=False, stabilize=5)
        70368442188091
        sage: matrix_integer_dense_hnf.det_given_divisor(a, 1, proof=True)
        70368442188091

    TESTS::

        sage: m = diagonal_matrix(ZZ, 68, [2]*66 + [1,1])
        sage: m.det()
        73786976294838206464
    """
    p = max_det_prime(A.nrows())
    z_mod = []
    moduli = []
    assert d != 0
    z_so_far = 1
    N_so_far = 1
    if proof:
        N = 1
        B = (2 * 10**A.hadamard_bound()) // d + 1
        dd = d
        # bad verbose statement, since computing the log overflows!
        est = int(RR(B).log() / RR(p).log()) + 1
        cnt = 1
        verbose("Multimodular det -- need to use about %s primes." % est,
                level=1)
        while N < B:
            if d % p != 0:
                tm = cputime()
                dd, z_so_far, N_so_far = det_from_modp_and_divisor(
                    A, d, p, z_mod, moduli, z_so_far, N_so_far)
                N *= p
                verbose(
                    "computed det mod p=%s which is %s (of about %s)" %
                    (p, cnt, est), tm)
            p = previous_prime(p)
            cnt += 1
        return dd
    else:
        val = []
        while True:
            if d % p:
                tm = cputime()
                dd, z_so_far, N_so_far = det_from_modp_and_divisor(
                    A, d, p, z_mod, moduli, z_so_far, N_so_far)
                verbose("computed det mod %s" % p, tm)
                val.append(dd)
                if len(val) >= stabilize and len(set(val[-stabilize:])) == 1:
                    return val[-1]
            p = previous_prime(p)
Exemplo n.º 30
0
 def vertex_to_angle(v):
     # v==0 corresponds to pi/2
     return -2 * pi * RR(v) / self.r() + 5 * pi / 2