class HyperbolicRegularPolygon(HyperbolicPolygon): r""" Primitive class for regular hyberbolic polygon type. See ``hyperbolic_regular_polygon?`` for information about plotting a hyperbolic regular polygon in the upper complex halfplane. INPUT: - ``sides`` -- number of sides of the polygon - ``i_angle`` -- interior angle of the polygon - ``center``-- center point as a complex number of the polygon EXAMPLES: Note that constructions should use :func:`hyperbolic_regular_polygon`:: sage: from sage.plot.hyperbolic_regular_polygon import HyperbolicRegularPolygon sage: print(HyperbolicRegularPolygon(5,pi/2,I, {})) Hyperbolic regular polygon (sides=5, i_angle=1/2*pi, center=1.00000000000000*I) The code verifies is there exists a compact hyperbolic regular polygon with the given data, checking .. MATH:: A(\mathcal{P}) = \pi(s-2) - s \cdot \alpha > 0, where `s` is ``sides`` and `\alpha` is ``i_angle`. This raises an error if the ``i_angle`` is less than the minimum to generate a compact polygon:: sage: from sage.plot.hyperbolic_regular_polygon import HyperbolicRegularPolygon sage: P = HyperbolicRegularPolygon(4, pi/2, I, {}) Traceback (most recent call last): ... ValueError: there exists no hyperbolic regular compact polygon, for sides=4 the interior angle must be less than 1/2*pi It is an error to give a center outside the upper half plane in this model :: sage: from sage.plot.hyperbolic_regular_polygon import HyperbolicRegularPolygon sage: P = HyperbolicRegularPolygon(4, pi/4, 1-I, {}) Traceback (most recent call last): ... ValueError: center: 1.00000000000000 - 1.00000000000000*I is not a valid point in the upper half plane model of the hyperbolic plane TESTS:: sage: from sage.plot.hyperbolic_regular_polygon import HyperbolicRegularPolygon sage: P = HyperbolicRegularPolygon(4, -pi/4, I, {}) Traceback (most recent call last): ... ValueError: interior angle -1/4*pi must be in (0, pi) interval sage: from sage.plot.hyperbolic_regular_polygon import HyperbolicRegularPolygon sage: P=HyperbolicRegularPolygon(16, 3*pi/2, I, {}) Traceback (most recent call last): ... ValueError: interior angle 3/2*pi must be in (0, pi) interval sage: from sage.plot.hyperbolic_regular_polygon import HyperbolicRegularPolygon sage: P = HyperbolicRegularPolygon(2, pi/10, I, {}) Traceback (most recent call last): ... ValueError: degenerated polygons (sides<=2) are not supported """ def __init__(self, sides, i_angle, center, options): """ Initialize HyperbolicRegularPolygon. EXAMPLES:: sage: from sage.plot.hyperbolic_regular_polygon import HyperbolicRegularPolygon sage: print(HyperbolicRegularPolygon(5,pi/2,I, {})) Hyperbolic regular polygon (sides=5, i_angle=1/2*pi, center=1.00000000000000*I) """ self.center = CC(center) if self.center.imag() <= 0 : raise ValueError("center: %s is not a valid point in the upper half plane model of the hyperbolic plane"%(self.center)) if sides < 3 : raise ValueError("degenerated polygons (sides<=2) are not supported") if i_angle <=0 or i_angle >= pi: raise ValueError("interior angle %s must be in (0, pi) interval"%(i_angle)) if pi*(sides-2) - sides*i_angle <= 0 : raise ValueError("there exists no hyperbolic regular compact polygon, for sides=%s the interior angle must be less than %s"%(sides, pi * (sides-2) / sides)) self.sides = sides self.i_angle = i_angle beta = 2 * pi / self.sides # compute the rotation angle to be used ahead alpha = self.i_angle / Integer(2) I = CC(0, 1) # compute using cosine theorem the radius of the circumscribed circle # using the triangle formed by the radius and the three known angles r = arccosh(cot(alpha) * (1 + cos(beta)) / sin(beta)) # The first point will be always on the imaginary axis limited # to 8 digits for efficiency in the subsequent calculations. z_0 = [I*(e**r).n(digits=8)] # Compute the dilation isometry used to move the center # from I to the imaginary part of the given center. scale = self.center.imag() # Compute the parabolic isometry to move the center to the # real part of the given center. h_disp = self.center.real() d_z_k = [z_0[0]*scale + h_disp] #d_k has the points for the polygon in the given center z_k = z_0 #z_k has the Re(z)>0 vertices for the I centered polygon r_z_k = [] #r_z_k has the Re(z)<0 vertices if is_odd(self.sides): vert = (self.sides - 1) / 2 else: vert = self.sides / 2 - 1 for k in range(0, vert): # Compute with 8 digits to accelerate calculations new_z_k = self._i_rotation(z_k[-1], beta).n(digits=8) z_k = z_k + [new_z_k] d_z_k = d_z_k + [new_z_k * scale + h_disp] r_z_k=[-(new_z_k).conjugate() * scale + h_disp] + r_z_k if is_odd(self.sides): HyperbolicPolygon.__init__(self, d_z_k + r_z_k, options) else: z_opo = [I * (e**(-r)).n(digits=8) * scale + h_disp] HyperbolicPolygon.__init__(self, d_z_k + z_opo + r_z_k, options) def _repr_(self): """ String representation of HyperbolicRegularPolygon. TESTS:: sage: from sage.plot.hyperbolic_regular_polygon import HyperbolicRegularPolygon sage: HyperbolicRegularPolygon(5,pi/2,I, {})._repr_() 'Hyperbolic regular polygon (sides=5, i_angle=1/2*pi, center=1.00000000000000*I)' """ return ("Hyperbolic regular polygon (sides=%s, i_angle=%s, center=%s)" % (self.sides, self.i_angle, self.center)) def _i_rotation(self, z, alpha): r""" Return the resulting point after applying a hyperbolic rotation centered at `0 + i` and angle ``alpha`` to ``z``. INPUT: - ``z``-- point in the upper complex halfplane to which apply the isometry - ``alpha``-- angle of rotation (radians,counterwise) OUTPUT: - rotated point in the upper complex halfplane TESTS:: sage: from sage.plot.hyperbolic_regular_polygon import HyperbolicRegularPolygon sage: P = HyperbolicRegularPolygon(4, pi/4, 1+I, {}) sage: P._i_rotation(2+I, pi/2) I - 2 """ _a = alpha / 2 _c = cos(_a) _s = sin(_a) G = matrix([[_c, _s], [-_s, _c]]) return (G[0][0] * z + G[0][1]) / (G[1][0] * z + G[1][1])
def julia_plot(c=-1, x_center=0.0, y_center=0.0, image_width=4.0, max_iteration=500, pixel_count=500, base_color='steelblue', iteration_level=1, number_of_colors=50, point_color='yellow', interact=False, mandelbrot=True, period=None): r""" Plots the Julia set of a given complex `c` value. Users can specify whether they would like to display the Mandelbrot side by side with the Julia set. The Julia set of a given `c` value is the set of complex numbers for which the function `Q_c(z)=z^2+c` is bounded under iteration. The Julia set can be visualized by plotting each point in the set in the complex plane. Julia sets are examples of fractals when plotted in the complex plane. ALGORITHM: Define the map `Q_c(z) = z^2 + c` for some `c \in \mathbb{C}`. For every `p \in \mathbb{C}`, if `|Q_{c}^{k}(p)| > 2` for some `k \geq 0`, then `Q_{c}^{n}(p) \to \infty`. Let `N` be the maximum number of iterations. Compute the first `N` points on the orbit of `p` under `Q_c`. If for any `k < N`, `|Q_{c}^{k}(p)| > 2`, we stop the iteration and assign a color to the point `p` based on how quickly `p` escaped to infinity under iteration of `Q_c`. If `|Q_{c}^{i}(p)| \leq 2` for all `i \leq N`, we assume `p` is in the Julia set and assign the point `p` the color black. INPUT: - ``c`` -- complex (optional - default: ``-1``), complex point `c` that determines the Julia set. - ``period`` -- list (optional - default: ``None``), returns the Julia set for a random `c` value with the given (formal) cycle structure. - ``mandelbrot`` -- boolean (optional - default: ``True``), when set to ``True``, an image of the Mandelbrot set is appended to the right of the Julia set. - ``point_color`` -- RGB color (optional - default: ``'tomato'``), color of the point `c` in the Mandelbrot set (any valid input for Color). - ``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 `Q_c(z)`. - ``pixel_count`` -- long (optional - default: ``500``), side length of image in number of pixels. - ``base_color`` -- RGB color (optional - default: ``'steelblue'``), color used to determine the coloring of set (any valid input for Color). - ``iteration_level`` -- 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 Julia set in the complex plane. EXAMPLES:: sage: julia_plot() 1001x500px 24-bit RGB image To display only the Julia set, set ``mandelbrot`` to ``False``:: sage: julia_plot(mandelbrot=False) 500x500px 24-bit RGB image To display an interactive plot of the Julia set in the Notebook, set ``interact`` to ``True``:: sage: julia_plot(interact=True) interactive(children=(FloatSlider(value=-1.0, description=u'Real c'... To return the Julia set of a random `c` value with (formal) cycle structure `(2,3)`, set ``period = [2,3]``:: sage: julia_plot(period=[2,3]) 1001x500px 24-bit RGB image To return all of the Julia sets of `c` values with (formal) cycle structure `(2,3)`:: sage: period = [2,3] # not tested ....: R.<c> = QQ[] ....: P.<x,y> = ProjectiveSpace(R,1) ....: f = DynamicalSystem([x^2+c*y^2, y^2]) ....: L = f.dynatomic_polynomial(period).subs({x:0,y:1}).roots(ring=CC) ....: c_values = [k[0] for k in L] ....: for c in c_values: ....: julia_plot(c) """ if period is not None: R = PolynomialRing(QQ, 'c') c = R.gen() x, y = ProjectiveSpace(R, 1, 'x,y').gens() f = DynamicalSystem([x**2 + c * y**2, y**2]) L = f.dynatomic_polynomial(period).subs({x: 0, y: 1}).roots(ring=CC) c = L[randint(0, len(L) - 1)][0] c = CC(c) c_real = c.real() c_imag = c.imag() base_color = Color(base_color) point_color = Color(point_color) if interact: from ipywidgets.widgets import FloatSlider, IntSlider, ColorPicker, interact widgets = dict( c_real = FloatSlider(min=-2.0, max=2.0, step=EPS, value=c_real, description="Real c"), c_imag = FloatSlider(min=-2.0, max=2.0, step=EPS, value=c_imag, description="Imag c"), 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="Image width"), max_iteration = IntSlider(min=0, max=600, value=max_iteration, description="Iterations"), pixel_count = IntSlider(min=10, max=600, value=pixel_count, description="Pixels"), level_sep = IntSlider(min=1, max=20, value=iteration_level, description="Color sep"), color_num = IntSlider(min=1, max=100, value=number_of_colors, description="# Colors"), base_color = ColorPicker(value=base_color.html_color(), description="Base color"), ) if mandelbrot: widgets["point_color"] = ColorPicker(value=point_color.html_color(), description="Point color") return interact(**widgets).widget(julia_helper) else: return interact(**widgets).widget(fast_julia_plot) if mandelbrot: return julia_helper(c_real, c_imag, x_center, y_center, image_width, max_iteration, pixel_count, iteration_level, number_of_colors, base_color, point_color) else: return fast_julia_plot(c_real, c_imag, x_center, y_center, image_width, max_iteration, pixel_count, iteration_level, number_of_colors, base_color)
def julia_plot(f=None, **kwds): r""" Plots the Julia set of a given polynomial ``f``. Users can specify whether they would like to display the Mandelbrot side by side with the Julia set with the ``mandelbrot`` argument. If ``f`` is not specified, this method defaults to `f(z) = z^2-1`. The Julia set of a polynomial ``f`` is the set of complex numbers `z` for which the function `f(z)` is bounded under iteration. The Julia set can be visualized by plotting each point in the set in the complex plane. Julia sets are examples of fractals when plotted in the complex plane. ALGORITHM: Let `R_c = \bigl(1 + \sqrt{1 + 4|c|}\bigr)/2` if the polynomial is of the form `f(z) = z^2 + c`; otherwise, let `R_c = 2`. For every `p \in \mathbb{C}`, if `|f^{k}(p)| > R_c` for some `k \geq 0`, then `f^{n}(p) \to \infty`. Let `N` be the maximum number of iterations. Compute the first `N` points on the orbit of `p` under `f`. If for any `k < N`, `|f^{k}(p)| > R_c`, we stop the iteration and assign a color to the point `p` based on how quickly `p` escaped to infinity under iteration of `f`. If `|f^{i}(p)| \leq R_c` for all `i \leq N`, we assume `p` is in the Julia set and assign the point `p` the color black. INPUT: - ``f`` -- input polynomial (optional - default: ``z^2 - 1``). - ``period`` -- list (optional - default: ``None``), returns the Julia set for a random `c` value with the given (formal) cycle structure. - ``mandelbrot`` -- boolean (optional - default: ``True``), when set to ``True``, an image of the Mandelbrot set is appended to the right of the Julia set. - ``point_color`` -- RGB color (optional - default: ``'tomato'``), color of the point `c` in the Mandelbrot set (any valid input for Color). - ``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(z)`. - ``pixel_count`` -- long (optional - default: ``500``), side length of image in number of pixels. - ``base_color`` -- hex color (optional - default: ``'steelblue'``), color used to determine the coloring of set (any valid input for Color). - ``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 Julia set in the complex plane. .. TODO:: Implement the side-by-side Mandelbrot-Julia plots for general one-parameter families of polynomials. EXAMPLES: The default ``f`` is `z^2 - 1`:: sage: julia_plot() 1001x500px 24-bit RGB image To display only the Julia set, set ``mandelbrot`` to ``False``:: sage: julia_plot(mandelbrot=False) 500x500px 24-bit RGB image :: sage: R.<z> = CC[] sage: f = z^3 - z + 1 sage: julia_plot(f) 500x500px 24-bit RGB image To display an interactive plot of the Julia set in the Notebook, set ``interact`` to ``True``. (This is only implemented for polynomials of the form ``f = z^2 + c``):: sage: julia_plot(interact=True) interactive(children=(FloatSlider(value=-1.0, description=u'Real c'... :: sage: R.<z> = CC[] sage: f = z^2 + 1/2 sage: julia_plot(f,interact=True) interactive(children=(FloatSlider(value=0.5, description=u'Real c'... To return the Julia set of a random `c` value with (formal) cycle structure `(2,3)`, set ``period = [2,3]``:: sage: julia_plot(period=[2,3]) 1001x500px 24-bit RGB image To return all of the Julia sets of `c` values with (formal) cycle structure `(2,3)`:: sage: period = [2,3] # not tested ....: R.<c> = QQ[] ....: P.<x,y> = ProjectiveSpace(R,1) ....: f = DynamicalSystem([x^2+c*y^2, y^2]) ....: L = f.dynatomic_polynomial(period).subs({x:0,y:1}).roots(ring=CC) ....: c_values = [k[0] for k in L] ....: for c in c_values: ....: julia_plot(c) Polynomial maps can be defined over a polynomial ring or a fraction field, so long as ``f`` is polynomial:: sage: R.<z> = CC[] sage: f = z^2 - 1 sage: julia_plot(f) 1001x500px 24-bit RGB image :: sage: R.<z> = CC[] sage: K = R.fraction_field(); z = K.gen() sage: f = z^2-1 sage: julia_plot(f) 1001x500px 24-bit RGB image Interact functionality is not implemented if the polynomial is not of the form `f = z^2 + c`:: sage: R.<z> = CC[] sage: f = z^3 + 1 sage: julia_plot(f, interact=True) Traceback (most recent call last): ... NotImplementedError: The interactive plot is only implemented for ... """ # extract keyword arguments period = kwds.pop("period", None) mandelbrot = kwds.pop("mandelbrot", True) point_color = kwds.pop("point_color", 'tomato') 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", 500) pixel_count = kwds.pop("pixel_count", 500) base_color = kwds.pop("base_color", 'steelblue') level_sep = kwds.pop("level_sep", 1) number_of_colors = kwds.pop("number_of_colors", 30) interacts = kwds.pop("interact", False) f_is_default_after_all = None if period: # pick a random c with the specified period R = PolynomialRing(CC, 'c') c = R.gen() x, y = ProjectiveSpace(R, 1, 'x,y').gens() F = DynamicalSystem([x**2 + c * y**2, y**2]) L = F.dynatomic_polynomial(period).subs({x: 0, y: 1}).roots(ring=CC) c = L[randint(0, len(L) - 1)][0] base_color = Color(base_color) point_color = Color(point_color) EPS = 0.00001 if f is not None and period is None: # f user-specified and no period given # try to coerce f to live in a polynomial ring S = PolynomialRing(CC, names='z') z = S.gen() try: f_poly = S(f) except TypeError: R = f.parent() if not (R.is_integral_domain() and (CC.is_subring(R) or CDF.is_subring(R))): raise ValueError('Given `f` must be a complex polynomial.') else: raise NotImplementedError( 'Julia sets not implemented for rational functions.') if (f_poly - z * z) in CC: # f is specified and of the form z^2 + c. f_is_default_after_all = True c = f_poly - z * z else: # f is specified and not of the form z^2 + c if interacts: raise NotImplementedError( "The interactive plot is only implemented for " "polynomials of the form f = z^2 + c.") else: return general_julia(f_poly, x_center, y_center, image_width, max_iteration, pixel_count, level_sep, number_of_colors, base_color) # otherwise we can use fast_julia_plot for z^2 + c if f_is_default_after_all or f is None or period is not None: # specify default c = -1 value if f and period were not specified if not f_is_default_after_all and period is None: c = -1 c = CC(c) c_real = c.real() c_imag = c.imag() if interacts: # set widgets from ipywidgets.widgets import FloatSlider, IntSlider, \ ColorPicker, interact widgets = dict( c_real=FloatSlider(min=-2.0, max=2.0, step=EPS, value=c_real, description="Real c"), c_imag=FloatSlider(min=-2.0, max=2.0, step=EPS, value=c_imag, description="Imag c"), 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=base_color.html_color(), description="Base color"), ) if mandelbrot: widgets["point_color"] = ColorPicker( value=point_color.html_color(), description="Point color") return interact(**widgets).widget(julia_helper) else: return interact(**widgets).widget(fast_julia_plot) elif mandelbrot: # non-interactive with mandelbrot return julia_helper(c_real, c_imag, x_center, y_center, image_width, max_iteration, pixel_count, level_sep, number_of_colors, base_color, point_color) else: # non-interactive without mandelbrot return fast_julia_plot(c_real, c_imag, x_center, y_center, image_width, max_iteration, pixel_count, level_sep, number_of_colors, base_color)
def julia_plot(c=-1, x_center=0.0, y_center=0.0, image_width=4.0, max_iteration=500, pixel_count=500, base_color='steelblue', iteration_level=1, number_of_colors=50, point_color='yellow', interact=False, mandelbrot=True, period=None): r""" Plots the Julia set of a given complex `c` value. Users can specify whether they would like to display the Mandelbrot side by side with the Julia set. The Julia set of a given `c` value is the set of complex numbers for which the function `Q_c(z)=z^2+c` is bounded under iteration. The Julia set can be visualized by plotting each point in the set in the complex plane. Julia sets are examples of fractals when plotted in the complex plane. ALGORITHM: Define the map `Q_c(z) = z^2 + c` for some `c \in \mathbb{C}`. For every `p \in \mathbb{C}`, if `|Q_{c}^{k}(p)| > 2` for some `k \geq 0`, then `Q_{c}^{n}(p) \to \infty`. Let `N` be the maximum number of iterations. Compute the first `N` points on the orbit of `p` under `Q_c`. If for any `k < N`, `|Q_{c}^{k}(p)| > 2`, we stop the iteration and assign a color to the point `p` based on how quickly `p` escaped to infinity under iteration of `Q_c`. If `|Q_{c}^{i}(p)| \leq 2` for all `i \leq N`, we assume `p` is in the Julia set and assign the point `p` the color black. INPUT: - ``c`` -- complex (optional - default: ``-1``), complex point `c` that determines the Julia set. - ``period`` -- list (optional - default: ``None``), returns the Julia set for a random `c` value with the given (formal) cycle structure. - ``mandelbrot`` -- boolean (optional - default: ``True``), when set to ``True``, an image of the Mandelbrot set is appended to the right of the Julia set. - ``point_color`` -- RGB color (optional - default: ``'tomato'``), color of the point `c` in the Mandelbrot set (any valid input for Color). - ``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 `Q_c(z)`. - ``pixel_count`` -- long (optional - default: ``500``), side length of image in number of pixels. - ``base_color`` -- RGB color (optional - default: ``'steelblue'``), color used to determine the coloring of set (any valid input for Color). - ``iteration_level`` -- 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 Julia set in the complex plane. EXAMPLES:: sage: julia_plot() 1001x500px 24-bit RGB image To display only the Julia set, set ``mandelbrot`` to ``False``:: sage: julia_plot(mandelbrot=False) 500x500px 24-bit RGB image To display an interactive plot of the Julia set in the Notebook, set ``interact`` to ``True``:: sage: julia_plot(interact=True) interactive(children=(FloatSlider(value=-1.0, description=u'Real c'... To return the Julia set of a random `c` value with (formal) cycle structure `(2,3)`, set ``period = [2,3]``:: sage: julia_plot(period=[2,3]) 1001x500px 24-bit RGB image To return all of the Julia sets of `c` values with (formal) cycle structure `(2,3)`:: sage: period = [2,3] # not tested ....: R.<c> = QQ[] ....: P.<x,y> = ProjectiveSpace(R,1) ....: f = DynamicalSystem([x^2+c*y^2, y^2]) ....: L = f.dynatomic_polynomial(period).subs({x:0,y:1}).roots(ring=CC) ....: c_values = [k[0] for k in L] ....: for c in c_values: ....: julia_plot(c) """ if period is not None: R = PolynomialRing(QQ, 'c') c = R.gen() x, y = ProjectiveSpace(R, 1, 'x,y').gens() f = DynamicalSystem([x**2 + c * y**2, y**2]) L = f.dynatomic_polynomial(period).subs({x: 0, y: 1}).roots(ring=CC) c = L[randint(0, len(L) - 1)][0] c = CC(c) c_real = c.real() c_imag = c.imag() base_color = Color(base_color) point_color = Color(point_color) if interact: from ipywidgets.widgets import FloatSlider, IntSlider, ColorPicker, interact widgets = dict( c_real=FloatSlider(min=-2.0, max=2.0, step=EPS, value=c_real, description="Real c"), c_imag=FloatSlider(min=-2.0, max=2.0, step=EPS, value=c_imag, description="Imag c"), 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="Image width"), max_iteration=IntSlider(min=0, max=600, value=max_iteration, description="Iterations"), pixel_count=IntSlider(min=10, max=600, value=pixel_count, description="Pixels"), level_sep=IntSlider(min=1, max=20, value=iteration_level, description="Color sep"), color_num=IntSlider(min=1, max=100, value=number_of_colors, description="# Colors"), base_color=ColorPicker(value=base_color.html_color(), description="Base color"), ) if mandelbrot: widgets["point_color"] = ColorPicker( value=point_color.html_color(), description="Point color") return interact(**widgets).widget(julia_helper) else: return interact(**widgets).widget(fast_julia_plot) if mandelbrot: return julia_helper(c_real, c_imag, x_center, y_center, image_width, max_iteration, pixel_count, iteration_level, number_of_colors, base_color, point_color) else: return fast_julia_plot(c_real, c_imag, x_center, y_center, image_width, max_iteration, pixel_count, iteration_level, number_of_colors, base_color)