Esempio n. 1
0
    def extensions(self, L):
        r"""
        Return all extensions of this valuation to ``L`` which has a larger
        constant field than the domain of this valuation.

        EXAMPLES::

            sage: K.<x> = FunctionField(QQ)
            sage: v = K.valuation(x^2 + 1)
            sage: L.<x> = FunctionField(GaussianIntegers().fraction_field())
            sage: v.extensions(L) # indirect doctest
            [(x - I)-adic valuation, (x + I)-adic valuation]

        """
        K = self.domain()
        if L is K:
            return [self]

        from sage.categories.function_fields import FunctionFields
        if L in FunctionFields() \
            and K.is_subring(L) \
            and L.base() is L \
            and L.constant_field() is not K.constant_field() \
            and K.constant_field().is_subring(L.constant_field()):
            # The above condition checks whether L is an extension of K that
            # comes from an extension of the field of constants
            # Condition "L.base() is L" is important so we do not call this
            # code for extensions from K(x) to K(x)(y)
            
            # We extend the underlying valuation on the polynomial ring
            W = self._base_valuation.extensions(L._ring)
            return [L.valuation(w) for w in W]

        return super(InducedFunctionFieldValuation_base, self).extensions(L)
Esempio n. 2
0
    def __init__(self, field):
        """
        TESTS::

            sage: from sage.rings.function_field.differential import DifferentialsSpaceFunctor
            sage: K.<x> = FunctionField(QQ)
            sage: DifferentialsSpaceFunctor(K)(K)
            Space of differentials of Rational function field in x over Rational Field

        """
        ConstructionFunctor.__init__(self, FunctionFields(),
                                     DifferentialsSpaces(field))
Esempio n. 3
0
    def create_key_and_extra_args_from_valuation_on_isomorphic_field(self, domain, valuation, to_valuation_domain, from_valuation_domain):
        r"""
        Create a unique key which identifies the valuation which is
        ``valuation`` after mapping through ``to_valuation_domain``.

        TESTS::

            sage: K.<x> = FunctionField(GF(2))
            sage: R.<y> = K[]
            sage: L.<y> = K.extension(y^2 + y + x^3)
            sage: v = K.valuation(1/x)
            sage: w = v.extension(L) # indirect doctest

        """
        from sage.categories.function_fields import FunctionFields
        if valuation.domain() not in FunctionFields():
            raise ValueError("valuation must be defined over an isomorphic function field but %r is not a function field"%(valuation.domain(),))

        from sage.categories.homset import Hom
        if to_valuation_domain not in Hom(domain, valuation.domain()):
            raise ValueError("to_valuation_domain must map from %r to %r but %r maps from %r to %r"%(domain, valuation.domain(), to_valuation_domain, to_valuation_domain.domain(), to_valuation_domain.codomain()))
        if from_valuation_domain not in Hom(valuation.domain(), domain):
            raise ValueError("from_valuation_domain must map from %r to %r but %r maps from %r to %r"%(valuation.domain(), domain, from_valuation_domain, from_valuation_domain.domain(), from_valuation_domain.codomain()))

        if domain is domain.base():
            # over rational function fields, we only support the map x |--> 1/x with another rational function field
            if valuation.domain() is not valuation.domain().base() or valuation.domain().constant_base_field() != domain.constant_base_field():
                raise NotImplementedError("maps must be isomorphisms with a rational function field over the same base field, not with %r"%(valuation.domain(),))
            if to_valuation_domain != domain.hom([~valuation.domain().gen()]):
                raise NotImplementedError("to_valuation_domain must be the map %r not %r"%(domain.hom([~valuation.domain().gen()]), to_valuation_domain))
            if from_valuation_domain != valuation.domain().hom([~domain.gen()]):
                raise NotImplementedError("from_valuation_domain must be the map %r not %r"%(valuation.domain().hom([domain.gen()]), from_valuation_domain))
            if domain != valuation.domain():
                # make it harder to create different representations of the same valuation
                # (nothing bad happens if we did, but >= and <= are only implemented when this is the case.)
                raise NotImplementedError("domain and valuation.domain() must be the same rational function field but %r is not %r"%(domain, valuation.domain()))
        else:
            if domain.base() is not valuation.domain().base():
                raise NotImplementedError("domain and valuation.domain() must have the same base field but %r is not %r"%(domain.base(), valuation.domain().base()))
            if to_valuation_domain != domain.hom([to_valuation_domain(domain.gen())]):
                raise NotImplementedError("to_valuation_domain must be trivial on the base fields but %r is not %r"%(to_valuation_domain, domain.hom([to_valuation_domain(domain.gen())])))
            if from_valuation_domain != valuation.domain().hom([from_valuation_domain(valuation.domain().gen())]):
                raise NotImplementedError("from_valuation_domain must be trivial on the base fields but %r is not %r"%(from_valuation_domain, valuation.domain().hom([from_valuation_domain(valuation.domain().gen())])))
            if to_valuation_domain(domain.gen()) == valuation.domain().gen():
                raise NotImplementedError("to_valuation_domain seems to be trivial but trivial maps would currently break partial orders of valuations")

        if from_valuation_domain(to_valuation_domain(domain.gen())) != domain.gen():
            # only a necessary condition
            raise ValueError("to_valuation_domain and from_valuation_domain are not inverses of each other")

        return (domain, (valuation, to_valuation_domain, from_valuation_domain)), {}
def is_FunctionField(x):
    """
    Return True if ``x`` is of function field type.

    EXAMPLES::

        sage: from sage.rings.function_field.function_field import is_FunctionField
        sage: is_FunctionField(QQ)
        False
        sage: is_FunctionField(FunctionField(QQ,'t'))
        True
    """
    if isinstance(x, FunctionField): return True
    return x in FunctionFields()
#  as published by the Free Software Foundation; either version 2 of
#  the License, or (at your option) any later version.
#                  http://www.gnu.org/licenses/
#*****************************************************************************

from sage.rings.ring import Field
from function_field_element import FunctionFieldElement, FunctionFieldElement_rational, FunctionFieldElement_polymod

from sage.misc.cachefunc import cached_method

#is needed for genus computation
from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
from sage.interfaces.all import singular

from sage.categories.function_fields import FunctionFields
CAT = FunctionFields()


def is_FunctionField(x):
    """
    Return True if ``x`` is of function field type.

    EXAMPLES::

        sage: from sage.rings.function_field.function_field import is_FunctionField
        sage: is_FunctionField(QQ)
        False
        sage: is_FunctionField(FunctionField(QQ,'t'))
        True
    """
    if isinstance(x, FunctionField): return True
Esempio n. 6
0
def _coerce_map_from_(target, source):
    r"""
    TESTS::

        sage: sys.path.append(os.getcwd()); from mac_lane import * # optional: standalone
        sage: K.<x> = FunctionField(QQ)
        sage: L.<x> = FunctionField(GaussianIntegers().fraction_field())
        sage: L.has_coerce_map_from(K)
        True

        sage: K.<x> = FunctionField(QQ)
        sage: R.<y> = K[]
        sage: L.<y> = K.extension(y^3 + 1)
        sage: K.<x> = FunctionField(GaussianIntegers().fraction_field())
        sage: R.<y> = K[]
        sage: M.<y> = K.extension(y^3 + 1)
        sage: M.has_coerce_map_from(L) # not tested, base morphism is not implemented
        True

        sage: K.<x> = FunctionField(QQ)
        sage: R.<I> = K[]
        sage: L.<I> = K.extension(I^2 + 1)
        sage: M.<x> = FunctionField(GaussianIntegers().fraction_field())
        sage: M.has_coerce_map_from(L) # not tested, base_morphism is not implemented
        True

    """
    from sage.categories.function_fields import FunctionFields
    if source in FunctionFields():
        if source.base_field() is source:
            if target.base_field() is target:
                # source and target are rational function fields
                if source.variable_name() == target.variable_name():
                    # ... in the same variable
                    base_coercion = target.constant_field().coerce_map_from(source.constant_field())
                    if base_coercion is not None:
                        return source.hom([target.gen()], base_morphism=base_coercion)
        else:
            # source is an extensions of rational function fields
            base_coercion = target.coerce_map_from(source.base_field())
            if base_coercion is not None:
                # the base field of source coerces into the base field of target
                target_polynomial = source.polynomial().map_coefficients(base_coercion)
                # try to find a root of the defining polynomial in target
                if target_polynomial(target.gen()) == 0:
                    # The defining polynomial of source has a root in target,
                    # therefore there is a map. To be sure that it is
                    # canonical, we require a root of the defining polynomial
                    # of target to be a root of the defining polynomial of
                    # source (and that the variables are named equally):
                    if source.variable_name() == target.variable_name():
                        return source.hom([target.gen()], base_morphism=base_coercion)

                roots = target_polynomial.roots()
                for root, _ in roots:
                    if target_polynomial(root) == 0:
                        # The defining polynomial of source has a root in target,
                        # therefore there is a map. To be sure that it is
                        # canonical, we require the names of the roots to match
                        if source.variable_name() == repr(root):
                            return source.hom([root], base_morphism=base_coercion)
    if source is target._ring:
        return DefaultConvertMap_unique_patched2(source, target)
    if source is target._ring.fraction_field():
        return DefaultConvertMap_unique_patched2(source, target)
Esempio n. 7
0
def make_function_field(K):
    r"""
    Return the function field isomorphic to this field, an isomorphism,
    and its inverse.

    INPUT:

    - ``K`` -- a field

    OUTPUT: A triple `(F,\phi,\psi)`, where `F` is a rational function field,
    `\phi:K\to F` is a field isomorphism and `\psi` the inverse of `\phi`.

    It is assumed that `K` is either the fraction field of a polynomial ring
    over a finite field `k`, or a finite simple extension of such a field.

    In the first case, `F=k_1(x)` is a rational function field over a finite
    field `k_1`, where `k_1` as an *absolute* finite field isomorphic to `k`.
    In the second case, `F` is a finite simple extension of a rational function
    field as in the first case.

    .. NOTE::

        this command seems to be partly superflous by now, because the residue
        of a valuation is already of type "function field" whenever this makes sense.
        However, even if `K` is a function field over a finite field, it is not
        guaranteed that the constant base field is a 'true' finite field, and then
        it is important to change that.

    """
    from mclf.curves.smooth_projective_curves import make_finite_field
    from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
    from sage.categories.function_fields import FunctionFields
    from sage.rings.function_field.function_field import is_FunctionField

    if is_FunctionField(K):
        k = K.constant_base_field()
        if k.is_finite() and hasattr(k, "base_field"):
            # k seems to be finite, but not a true finite field
            # we construct a true finite field k1 isomorphic to k
            # and F isomorphic to K with constant base field k1
            k1, phi, psi = make_finite_field(k)
            if hasattr(K, "polynomial"):
                # K is an extension of a rational function field
                K0 = K.rational_function_field()
                F0, phi0, psi0 = make_function_field(K0)
                f = K.polynomial().change_ring(phi0)
                F = F0.extension(f)
                return F, K.hom(F.gen(), phi0), F.hom(K.gen(), psi0)
            else:
                F = FunctionField(k1, K.variable_name())
                return F, K.hom(F.gen(), phi), F.hom(K.gen(), psi)
        else:
            return K, K.Hom(K).identity(), K.Hom(K).identity()

    if hasattr(K, "modulus") or hasattr(K, "polynomial"):
        # we hope that K is a simple finite extension of a field which is
        # isomorphic to a rational function field
        K_base = K.base_field()
        F_base, phi_base, psi_base = make_function_field(K_base)
        if hasattr(K, "modulus"):
            G = K.modulus()
        else:
            G = K.polynomial()
        R = G.parent()
        R_new = PolynomialRing(F_base, R.variable_name())
        G_new = R_new([phi_base(c) for c in G.list()])
        assert G_new.is_irreducible(), "G must be irreducible!"
        # F = F_base.extension(G_new, R.variable_name())
        F = F_base.extension(G_new, 'y')
        # phi0 = R.hom(F.gen(), F)
        # to construct phi:K=K_0[x]/(G) --> F=F_0[y]/(G),
        # we first 'map' from K to K_0[x]
        phi = K.hom(R.gen(), R, check=False)
        # then from K_0[x] to F_0[y]
        psi = R.hom(phi_base, R_new)
        # then from F_0[y] to F = F_0[y]/(G)
        phi = phi.post_compose(psi.post_compose(R_new.hom(F.gen(), F)))
        psi = F.hom(K.gen(), psi_base)
        return F, phi, psi
    else:
        # we hope that K is isomorphic to a rational function field over a
        # finite field
        if K in FunctionFields():
            # K is already a function field
            k = K.constant_base_field()
            k_new, phi_base, psi_base = make_finite_field(k)
            F = FunctionField(k_new, K.variable_name())
            phi = K.hom(F.gen(), phi_base)
            psi = F.hom(K.gen(), psi_base)
            return F, phi, psi
        elif hasattr(K, "function_field"):
            F1 = K.function_field()
            phi1 = F1.coerce_map_from(K)
            psi1 = F1.hom(K.gen())
            F, phi2, psi2 = make_function_field(F1)
            phi = phi1.post_compose(phi2)
            psi = psi2.post_compose(psi1)
            return F, phi, psi
        else:
            raise NotImplementedError
Esempio n. 8
0
    def extensions(self, L):
        r"""
        Return the extensions of this valuation to ``L``.

        EXAMPLES::

            sage: K.<x> = FunctionField(QQ)
            sage: v = K.valuation(x)
            sage: R.<y> = K[]
            sage: L.<y> = K.extension(y^2 - x)
            sage: v.extensions(L)
            [(x)-adic valuation]

        TESTS:

        Valuations over the infinite place::

            sage: v = K.valuation(1/x)
            sage: R.<y> = K[]
            sage: L.<y> = K.extension(y^2 - 1/(x^2 + 1))
            sage: sorted(v.extensions(L), key=str)
            [[ Valuation at the infinite place, v(y + 1/x) = 3 ]-adic valuation,
             [ Valuation at the infinite place, v(y - 1/x) = 3 ]-adic valuation]

        Iterated extensions over the infinite place::

            sage: K.<x> = FunctionField(GF(2))
            sage: R.<y> = K[]
            sage: L.<y> = K.extension(y^2 + y + x^3)
            sage: v = K.valuation(1/x)
            sage: w = v.extension(L)
            sage: R.<z> = L[]
            sage: M.<z> = L.extension(z^2 - y)
            sage: w.extension(M) # squarefreeness is not implemented here
            Traceback (most recent call last):
            ...
            NotImplementedError

        A case that caused some trouble at some point::

            sage: R.<x> = QQ[]
            sage: v = GaussValuation(R, QQ.valuation(2))

            sage: K.<x> = FunctionField(QQ)
            sage: v = K.valuation(v)

            sage: R.<y> = K[]
            sage: L.<y> = K.extension(y^3 - x^4 - 1)
            sage: v.extensions(L)
            [2-adic valuation]

        Test that this works in towers::

            sage: K.<x> = FunctionField(GF(2))
            sage: R.<y> = K[]
            sage: L.<y> = K.extension(y - x)
            sage: R.<z> = L[]
            sage: L.<z> = L.extension(z - y)
            sage: v = K.valuation(x)
            sage: v.extensions(L)
            [(x)-adic valuation]
        """
        K = self.domain()
        from sage.categories.function_fields import FunctionFields
        if L is K:
            return [self]
        if L in FunctionFields():
            if K.is_subring(L):
                if L.base() is K:
                    # L = K[y]/(G) is a simple extension of the domain of this valuation
                    G = L.polynomial()
                    if not G.is_monic():
                        G = G / G.leading_coefficient()
                    if any(self(c) < 0 for c in G.coefficients()):
                        # rewrite L = K[u]/(H) with H integral and compute the extensions
                        from sage.rings.valuation.gauss_valuation import GaussValuation
                        g = GaussValuation(G.parent(), self)
                        y_to_u, u_to_y, H = g.monic_integral_model(G)
                        M = K.extension(H, names=L.variable_names())
                        H_extensions = self.extensions(M)

                        from sage.rings.morphism import RingHomomorphism_im_gens
                        if type(y_to_u) == RingHomomorphism_im_gens and type(u_to_y) == RingHomomorphism_im_gens:
                            return [L.valuation((w, L.hom([M(y_to_u(y_to_u.domain().gen()))]), M.hom([L(u_to_y(u_to_y.domain().gen()))]))) for w in H_extensions]
                        raise NotImplementedError
                    return [L.valuation(w) for w in self.mac_lane_approximants(L.polynomial(), require_incomparability=True)]
                elif L.base() is not L and K.is_subring(L):
                    # recursively call this method for the tower of fields
                    from operator import add
                    from functools import reduce
                    A = [base_valuation.extensions(L) for base_valuation in self.extensions(L.base())]
                    return reduce(add, A, [])
                elif L.constant_field() is not K.constant_field() and K.constant_field().is_subring(L):
                    # subclasses should override this method and handle this case, so we never get here
                    raise NotImplementedError("Can not compute the extensions of %r from %r to %r since the base ring changes."%(self, self.domain(), L))
        raise NotImplementedError("extension of %r from %r to %r not implemented"%(self, K, L))
Esempio n. 9
0
    def create_key_and_extra_args(self, domain, prime):
        r"""
        Create a unique key which identifies the valuation given by ``prime``
        on ``domain``.

        TESTS:

        We specify a valuation on a function field by two different means and
        get the same object::

            sage: K.<x> = FunctionField(QQ)
            sage: v = K.valuation(x - 1) # indirect doctest

            sage: R.<x> = QQ[]
            sage: w = GaussValuation(R, valuations.TrivialValuation(QQ)).augmentation(x - 1, 1)
            sage: K.valuation(w) is v
            True

        The normalization is, however, not smart enough, to unwrap
        substitutions that turn out to be trivial::
        
            sage: w = GaussValuation(R, QQ.valuation(2))
            sage: w = K.valuation(w)
            sage: w is K.valuation((w, K.hom([~K.gen()]), K.hom([~K.gen()])))
            False

        """
        from sage.categories.function_fields import FunctionFields
        if domain not in FunctionFields():
            raise ValueError("Domain must be a function field.")

        if isinstance(prime, tuple):
            if len(prime) == 3:
                # prime is a triple of a valuation on another function field with
                # isomorphism information
                return self.create_key_and_extra_args_from_valuation_on_isomorphic_field(domain, prime[0], prime[1], prime[2])

        from sage.rings.valuation.valuation_space import DiscretePseudoValuationSpace
        if prime.parent() is DiscretePseudoValuationSpace(domain):
            # prime is already a valuation of the requested domain
            # if we returned (domain, prime), we would break caching
            # because this element has been created from a different key
            # Instead, we return the key that was used to create prime
            # so the caller gets back a correctly cached version of prime
            if not hasattr(prime, "_factory_data"):
               raise NotImplementedError("Valuations on function fields must be unique and come out of the FunctionFieldValuation factory but %r has been created by other means"%(prime,))
            return prime._factory_data[2], {}

        if prime in domain:
            # prime defines a place
            return self.create_key_and_extra_args_from_place(domain, prime)
        if prime.parent() is DiscretePseudoValuationSpace(domain._ring):
            # prime is a discrete (pseudo-)valuation on the polynomial ring
            # that the domain is constructed from
            return self.create_key_and_extra_args_from_valuation(domain, prime)
        if domain.base_field() is not domain:
            # prime might define a valuation on a subring of domain and have a
            # unique extension to domain
            base_valuation = domain.base_field().valuation(prime)
            return self.create_key_and_extra_args_from_valuation(domain, base_valuation)
        from sage.rings.ideal import is_Ideal
        if is_Ideal(prime):
            raise NotImplementedError("a place can not be given by an ideal yet")

        raise NotImplementedError("argument must be a place or a pseudo-valuation on a supported subring but %r does not satisfy this for the domain %r"%(prime, domain))
Esempio n. 10
0
def mandelbrot_plot(f=None, **kwds):
    r"""
    Plot of the Mandelbrot set for a one parameter family of polynomial maps.

    The family `f_c(z)` must have parent ``R`` of the
    form ``R.<z,c> = CC[]``.

    REFERENCE:

    [Dev2005]_

    INPUT:

    - ``f`` -- map (optional - default: ``z^2 + c``), polynomial family used to
      plot the Mandelbrot set.

    - ``parameter`` -- variable (optional - default: ``c``), parameter variable
      used to plot the Mandelbrot set.

    - ``x_center`` -- double (optional - default: ``-1.0``), Real part of center
      point.

    - ``y_center`` -- double (optional - default: ``0.0``), Imaginary part of
      center point.

    - ``image_width`` -- double (optional - default: ``4.0``), width of image
      in the complex plane.

    - ``max_iteration`` -- long (optional - default: ``500``), maximum number of
      iterations the map ``f_c(z)``.

    - ``pixel_count`` -- long (optional - default: ``500``), side length of
      image in number of pixels.

    - ``base_color`` -- RGB color (optional - default: ``[40, 40, 40]``) color
      used to determine the coloring of set.

    - ``level_sep`` -- long (optional - default: 1) number of iterations
      between each color level.

    - ``number_of_colors`` -- long (optional - default: 30) number of colors
      used to plot image.

    - ``interact`` -- boolean (optional - default: ``False``), controls whether
      plot will have interactive functionality.

    OUTPUT:

    24-bit RGB image of the Mandelbrot set in the complex plane.

    EXAMPLES:

    ::

        sage: mandelbrot_plot()
        500x500px 24-bit RGB image

    ::

        sage: mandelbrot_plot(pixel_count=1000)
        1000x1000px 24-bit RGB image

    ::

        sage: mandelbrot_plot(x_center=-1.11, y_center=0.2283, image_width=1/128, # long time
        ....: max_iteration=2000, number_of_colors=500, base_color=[40, 100, 100])
        500x500px 24-bit RGB image

    To display an interactive plot of the Mandelbrot in the Notebook, set
    ``interact`` to ``True``. (This is only implemented for ``z^2 + c``)::

        sage: mandelbrot_plot(interact=True)
        interactive(children=(FloatSlider(value=0.0, description=u'Real center', max=1.0, min=-1.0, step=1e-05),
        FloatSlider(value=0.0, description=u'Imag center', max=1.0, min=-1.0, step=1e-05),
        FloatSlider(value=4.0, description=u'Width', max=4.0, min=1e-05, step=1e-05),
        IntSlider(value=500, description=u'Iterations', max=1000),
        IntSlider(value=500, description=u'Pixels', max=1000, min=10),
        IntSlider(value=1, description=u'Color sep', max=20, min=1),
        IntSlider(value=30, description=u'# Colors', min=1),
        ColorPicker(value='#ff6347', description=u'Base color'), Output()),
        _dom_classes=(u'widget-interact',))

    ::

        sage: mandelbrot_plot(interact=True, x_center=-0.75, y_center=0.25,
        ....: image_width=1/2, number_of_colors=75)
        interactive(children=(FloatSlider(value=-0.75, description=u'Real center', max=1.0, min=-1.0, step=1e-05),
        FloatSlider(value=0.25, description=u'Imag center', max=1.0, min=-1.0, step=1e-05),
        FloatSlider(value=0.5, description=u'Width', max=4.0, min=1e-05, step=1e-05),
        IntSlider(value=500, description=u'Iterations', max=1000),
        IntSlider(value=500, description=u'Pixels', max=1000, min=10),
        IntSlider(value=1, description=u'Color sep', max=20, min=1),
        IntSlider(value=75, description=u'# Colors', min=1),
        ColorPicker(value='#ff6347', description=u'Base color'), Output()),
        _dom_classes=(u'widget-interact',))

    Polynomial maps can be defined over a multivariate polynomial ring or a
    univariate polynomial ring tower::

        sage: R.<z,c> = CC[]
        sage: f = z^2 + c
        sage: mandelbrot_plot(f)
        500x500px 24-bit RGB image

    ::

        sage: B.<c> = CC[]
        sage: R.<z> = B[]
        sage: f = z^5 + c
        sage: mandelbrot_plot(f)
        500x500px 24-bit RGB image

    When the polynomial is defined over a multivariate polynomial ring it is
    necessary to specify the parameter variable (default parameter is ``c``)::

        sage: R.<a,b> = CC[]
        sage: f = a^2 + b^3
        sage: mandelbrot_plot(f, parameter=b)
        500x500px 24-bit RGB image

    Interact functionality is not implemented for general polynomial maps::

        sage: R.<z,c> = CC[]
        sage: f = z^3 + c
        sage: mandelbrot_plot(f, interact=True)
        Traceback (most recent call last):
        ...
        NotImplementedError: Interact only implemented for z^2 + c
    """
    parameter = kwds.pop("parameter", None)
    x_center = kwds.pop("x_center", 0.0)
    y_center = kwds.pop("y_center", 0.0)
    image_width = kwds.pop("image_width", 4.0)
    max_iteration = kwds.pop("max_iteration", None)
    pixel_count = kwds.pop("pixel_count", 500)
    level_sep = kwds.pop("level_sep", 1)
    number_of_colors = kwds.pop("number_of_colors", 30)
    interacts = kwds.pop("interact", False)
    base_color = kwds.pop("base_color", Color('tomato'))
    # Check if user specified maximum number of iterations
    given_iterations = True
    if max_iteration is None:
        # Set default to 500 for z^2 + c map
        max_iteration = 500
        given_iterations = False

    from ipywidgets.widgets import FloatSlider, IntSlider, ColorPicker, interact
    widgets = dict(
        x_center=FloatSlider(min=-1.0,
                             max=1.0,
                             step=EPS,
                             value=x_center,
                             description="Real center"),
        y_center=FloatSlider(min=-1.0,
                             max=1.0,
                             step=EPS,
                             value=y_center,
                             description="Imag center"),
        image_width=FloatSlider(min=EPS,
                                max=4.0,
                                step=EPS,
                                value=image_width,
                                description="Width"),
        max_iteration=IntSlider(min=0,
                                max=1000,
                                value=max_iteration,
                                description="Iterations"),
        pixel_count=IntSlider(min=10,
                              max=1000,
                              value=pixel_count,
                              description="Pixels"),
        level_sep=IntSlider(min=1,
                            max=20,
                            value=level_sep,
                            description="Color sep"),
        color_num=IntSlider(min=1,
                            max=100,
                            value=number_of_colors,
                            description="# Colors"),
        base_color=ColorPicker(value=Color(base_color).html_color(),
                               description="Base color"),
    )

    if f is None:
        # Quadratic map f = z^2 + c

        if interacts:
            return interact(**widgets).widget(fast_mandelbrot_plot)

        else:
            return fast_mandelbrot_plot(x_center, y_center, image_width,
                                        max_iteration, pixel_count, level_sep,
                                        number_of_colors, base_color)

    else:
        if parameter is None:
            c = var('c')
            parameter = c

        P = f.parent()

        if P.base_ring() is CC or P.base_ring() is CDF:
            if is_FractionField(P):
                raise NotImplementedError(
                    "coefficients must be polynomials in the parameter")
            gen_list = list(P.gens())
            parameter = gen_list.pop(gen_list.index(parameter))
            variable = gen_list.pop()

        elif P.base_ring().base_ring() is CC or P.base_ring().base_ring(
        ) is CDF:
            if is_FractionField(P.base_ring()):
                raise NotImplementedError(
                    "coefficients must be polynomials in the parameter")
            phi = P.flattening_morphism()
            f = phi(f)
            gen_list = list(f.parent().gens())
            parameter = gen_list.pop(gen_list.index(parameter))
            variable = gen_list.pop()

        elif P.base_ring() in FunctionFields():
            raise NotImplementedError(
                "coefficients must be polynomials in the parameter")

        else:
            raise ValueError("base ring must be a complex field")

        if f == variable**2 + parameter:
            # Quadratic map f = z^2 + c
            if interacts:
                return interact(**widgets).widget(fast_mandelbrot_plot)

            else:
                return fast_mandelbrot_plot(x_center, y_center, image_width,
                                            max_iteration, pixel_count,
                                            level_sep, number_of_colors,
                                            base_color)
        else:
            if interacts:
                raise NotImplementedError(
                    "Interact only implemented for z^2 + c")
            else:
                # Set default of max_iteration to 50 for general polynomial maps
                # This prevents the function from being very slow by default
                if not given_iterations:
                    max_iteration = 50

                # Mandelbrot of General Polynomial Map
                return polynomial_mandelbrot(f, parameter, x_center, y_center, \
                 image_width, max_iteration, pixel_count, level_sep, \
                 number_of_colors, base_color)
Esempio n. 11
0
def make_function_field(K):
    r"""
    Return the function field isomorphic to this field, an isomorphism,
    and its inverse.

    INPUT:

    - ``K`` -- a field

    OUTPUT: A triple `(F,\phi,\psi)`, where `F` is a rational function field,
    `\phi:K\to F` is a field isomorphism and `\psi` the inverse of `\phi`.

    It is assumed that `K` is either the fraction field of a polynomial ring
    over a finite field `k`, or a finite simple extension of such a field.

    In the first case, `F=k_1(x)` is a rational function field over a finite
    field `k_1`, where `k_1` as an *absolute* finite field isomorphic to `k`.
    In the second case, `F` is a finite simple extension of a rational function
    field as in the first case.

    """
    from mclf.curves.smooth_projective_curves import make_finite_field
    from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
    from sage.categories.function_fields import FunctionFields

    if hasattr(K, "modulus") or hasattr(K, "polynomial"):
        # we hope that K is a simple finite extension of a field which is
        # isomorphic to a rational function field
        K_base = K.base_field()
        F_base, phi_base, psi_base = make_function_field(K_base)
        if hasattr(K, "modulus"):
            G = K.modulus()
        else:
            G = K.polynomial()
        R = G.parent()
        R_new = PolynomialRing(F_base, R.variable_name())
        G_new = R_new([phi_base(c) for c in G.list()])
        assert G_new.is_irreducible(), "G must be irreducible!"
        # F = F_base.extension(G_new, R.variable_name())
        F = F_base.extension(G_new, 'y')
        # phi0 = R.hom(F.gen(), F)
        # to construct phi:K=K_0[x]/(G) --> F=F_0[y]/(G),
        # we first 'map' from K to K_0[x]
        phi = K.hom(R.gen(), R, check=False)
        # then from K_0[x] to F_0[y]
        psi = R.hom(phi_base, R_new)
        # then from F_0[y] to F = F_0[y]/(G)
        phi = phi.post_compose(psi.post_compose(R_new.hom(F.gen(), F)))
        psi = F.hom(K.gen(), psi_base)
        return F, phi, psi
    else:
        # we hope that K is isomorphic to a rational function field over a
        # finite field
        if K in FunctionFields():
            # K is already a function field
            k = K.constant_base_field()
            k_new, phi_base, psi_base = make_finite_field(k)
            F = FunctionField(k_new, K.variable_name())
            phi = K.hom(F.gen(), phi_base)
            psi = F.hom(K.gen(), psi_base)
            return F, phi, psi
        elif hasattr(K, "function_field"):
            F1 = K.function_field()
            phi1 = F1.coerce_map_from(K)
            psi1 = F1.hom(K.gen())
            F, phi2, psi2 = make_function_field(F1)
            phi = phi1.post_compose(phi2)
            psi = psi2.post_compose(psi1)
            return F, phi, psi
        else:
            raise NotImplementedError