passagemath-symbolics 10.6.43__cp314-cp314t-musllinux_1_2_x86_64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of passagemath-symbolics might be problematic. Click here for more details.

Files changed (171) hide show
  1. passagemath_symbolics/__init__.py +3 -0
  2. passagemath_symbolics-10.6.43.dist-info/METADATA +187 -0
  3. passagemath_symbolics-10.6.43.dist-info/RECORD +171 -0
  4. passagemath_symbolics-10.6.43.dist-info/WHEEL +5 -0
  5. passagemath_symbolics-10.6.43.dist-info/top_level.txt +3 -0
  6. sage/all__sagemath_symbolics.py +17 -0
  7. sage/calculus/all.py +14 -0
  8. sage/calculus/calculus.py +2826 -0
  9. sage/calculus/desolvers.py +1866 -0
  10. sage/calculus/predefined.py +51 -0
  11. sage/calculus/tests.py +225 -0
  12. sage/calculus/var.cpython-314t-x86_64-linux-musl.so +0 -0
  13. sage/calculus/var.pyx +401 -0
  14. sage/dynamics/all__sagemath_symbolics.py +6 -0
  15. sage/dynamics/complex_dynamics/all.py +5 -0
  16. sage/dynamics/complex_dynamics/mandel_julia.py +765 -0
  17. sage/dynamics/complex_dynamics/mandel_julia_helper.cpython-314t-x86_64-linux-musl.so +0 -0
  18. sage/dynamics/complex_dynamics/mandel_julia_helper.pyx +1035 -0
  19. sage/ext/all__sagemath_symbolics.py +1 -0
  20. sage/ext_data/kenzo/CP2.txt +45 -0
  21. sage/ext_data/kenzo/CP3.txt +349 -0
  22. sage/ext_data/kenzo/CP4.txt +4774 -0
  23. sage/ext_data/kenzo/README.txt +49 -0
  24. sage/ext_data/kenzo/S4.txt +20 -0
  25. sage/ext_data/magma/latex/latex.m +1021 -0
  26. sage/ext_data/magma/latex/latex.spec +1 -0
  27. sage/ext_data/magma/sage/basic.m +356 -0
  28. sage/ext_data/magma/sage/sage.spec +1 -0
  29. sage/ext_data/magma/spec +9 -0
  30. sage/geometry/all__sagemath_symbolics.py +8 -0
  31. sage/geometry/hyperbolic_space/all.py +5 -0
  32. sage/geometry/hyperbolic_space/hyperbolic_coercion.py +743 -0
  33. sage/geometry/hyperbolic_space/hyperbolic_constants.py +5 -0
  34. sage/geometry/hyperbolic_space/hyperbolic_geodesic.py +2409 -0
  35. sage/geometry/hyperbolic_space/hyperbolic_interface.py +206 -0
  36. sage/geometry/hyperbolic_space/hyperbolic_isometry.py +1082 -0
  37. sage/geometry/hyperbolic_space/hyperbolic_model.py +1502 -0
  38. sage/geometry/hyperbolic_space/hyperbolic_point.py +621 -0
  39. sage/geometry/riemannian_manifolds/all.py +7 -0
  40. sage/geometry/riemannian_manifolds/parametrized_surface3d.py +1632 -0
  41. sage/geometry/riemannian_manifolds/surface3d_generators.py +461 -0
  42. sage/interfaces/all__sagemath_symbolics.py +1 -0
  43. sage/interfaces/magma.py +3017 -0
  44. sage/interfaces/magma_free.py +92 -0
  45. sage/interfaces/maple.py +1397 -0
  46. sage/interfaces/mathematica.py +1345 -0
  47. sage/interfaces/mathics.py +1312 -0
  48. sage/interfaces/sympy.py +1398 -0
  49. sage/interfaces/sympy_wrapper.py +197 -0
  50. sage/interfaces/tides.py +938 -0
  51. sage/libs/all__sagemath_symbolics.py +6 -0
  52. sage/manifolds/all.py +7 -0
  53. sage/manifolds/calculus_method.py +555 -0
  54. sage/manifolds/catalog.py +437 -0
  55. sage/manifolds/chart.py +4019 -0
  56. sage/manifolds/chart_func.py +3419 -0
  57. sage/manifolds/continuous_map.py +2183 -0
  58. sage/manifolds/continuous_map_image.py +155 -0
  59. sage/manifolds/differentiable/affine_connection.py +2475 -0
  60. sage/manifolds/differentiable/all.py +1 -0
  61. sage/manifolds/differentiable/automorphismfield.py +1383 -0
  62. sage/manifolds/differentiable/automorphismfield_group.py +604 -0
  63. sage/manifolds/differentiable/bundle_connection.py +1445 -0
  64. sage/manifolds/differentiable/characteristic_cohomology_class.py +1840 -0
  65. sage/manifolds/differentiable/chart.py +1241 -0
  66. sage/manifolds/differentiable/curve.py +1028 -0
  67. sage/manifolds/differentiable/de_rham_cohomology.py +541 -0
  68. sage/manifolds/differentiable/degenerate.py +559 -0
  69. sage/manifolds/differentiable/degenerate_submanifold.py +1671 -0
  70. sage/manifolds/differentiable/diff_form.py +1658 -0
  71. sage/manifolds/differentiable/diff_form_module.py +1062 -0
  72. sage/manifolds/differentiable/diff_map.py +1315 -0
  73. sage/manifolds/differentiable/differentiable_submanifold.py +291 -0
  74. sage/manifolds/differentiable/examples/all.py +1 -0
  75. sage/manifolds/differentiable/examples/euclidean.py +2517 -0
  76. sage/manifolds/differentiable/examples/real_line.py +897 -0
  77. sage/manifolds/differentiable/examples/sphere.py +1186 -0
  78. sage/manifolds/differentiable/examples/symplectic_space.py +187 -0
  79. sage/manifolds/differentiable/examples/symplectic_space_test.py +40 -0
  80. sage/manifolds/differentiable/integrated_curve.py +4035 -0
  81. sage/manifolds/differentiable/levi_civita_connection.py +841 -0
  82. sage/manifolds/differentiable/manifold.py +4254 -0
  83. sage/manifolds/differentiable/manifold_homset.py +1826 -0
  84. sage/manifolds/differentiable/metric.py +3032 -0
  85. sage/manifolds/differentiable/mixed_form.py +1507 -0
  86. sage/manifolds/differentiable/mixed_form_algebra.py +559 -0
  87. sage/manifolds/differentiable/multivector_module.py +800 -0
  88. sage/manifolds/differentiable/multivectorfield.py +1520 -0
  89. sage/manifolds/differentiable/poisson_tensor.py +268 -0
  90. sage/manifolds/differentiable/pseudo_riemannian.py +755 -0
  91. sage/manifolds/differentiable/pseudo_riemannian_submanifold.py +1839 -0
  92. sage/manifolds/differentiable/scalarfield.py +1343 -0
  93. sage/manifolds/differentiable/scalarfield_algebra.py +472 -0
  94. sage/manifolds/differentiable/symplectic_form.py +910 -0
  95. sage/manifolds/differentiable/symplectic_form_test.py +220 -0
  96. sage/manifolds/differentiable/tangent_space.py +412 -0
  97. sage/manifolds/differentiable/tangent_vector.py +616 -0
  98. sage/manifolds/differentiable/tensorfield.py +4665 -0
  99. sage/manifolds/differentiable/tensorfield_module.py +963 -0
  100. sage/manifolds/differentiable/tensorfield_paral.py +2450 -0
  101. sage/manifolds/differentiable/tensorfield_paral_test.py +16 -0
  102. sage/manifolds/differentiable/vector_bundle.py +1728 -0
  103. sage/manifolds/differentiable/vectorfield.py +1717 -0
  104. sage/manifolds/differentiable/vectorfield_module.py +2445 -0
  105. sage/manifolds/differentiable/vectorframe.py +1832 -0
  106. sage/manifolds/family.py +270 -0
  107. sage/manifolds/local_frame.py +1490 -0
  108. sage/manifolds/manifold.py +3090 -0
  109. sage/manifolds/manifold_homset.py +452 -0
  110. sage/manifolds/operators.py +359 -0
  111. sage/manifolds/point.py +994 -0
  112. sage/manifolds/scalarfield.py +3718 -0
  113. sage/manifolds/scalarfield_algebra.py +629 -0
  114. sage/manifolds/section.py +3111 -0
  115. sage/manifolds/section_module.py +831 -0
  116. sage/manifolds/structure.py +229 -0
  117. sage/manifolds/subset.py +2764 -0
  118. sage/manifolds/subsets/all.py +1 -0
  119. sage/manifolds/subsets/closure.py +131 -0
  120. sage/manifolds/subsets/pullback.py +885 -0
  121. sage/manifolds/topological_submanifold.py +891 -0
  122. sage/manifolds/trivialization.py +733 -0
  123. sage/manifolds/utilities.py +1348 -0
  124. sage/manifolds/vector_bundle.py +1342 -0
  125. sage/manifolds/vector_bundle_fiber.py +332 -0
  126. sage/manifolds/vector_bundle_fiber_element.py +111 -0
  127. sage/matrix/all__sagemath_symbolics.py +1 -0
  128. sage/matrix/matrix_symbolic_dense.cpython-314t-x86_64-linux-musl.so +0 -0
  129. sage/matrix/matrix_symbolic_dense.pxd +6 -0
  130. sage/matrix/matrix_symbolic_dense.pyx +1022 -0
  131. sage/matrix/matrix_symbolic_sparse.cpython-314t-x86_64-linux-musl.so +0 -0
  132. sage/matrix/matrix_symbolic_sparse.pxd +6 -0
  133. sage/matrix/matrix_symbolic_sparse.pyx +1029 -0
  134. sage/modules/all__sagemath_symbolics.py +1 -0
  135. sage/modules/vector_callable_symbolic_dense.py +105 -0
  136. sage/modules/vector_symbolic_dense.py +116 -0
  137. sage/modules/vector_symbolic_sparse.py +118 -0
  138. sage/rings/all__sagemath_symbolics.py +4 -0
  139. sage/rings/asymptotic/all.py +6 -0
  140. sage/rings/asymptotic/asymptotic_expansion_generators.py +1485 -0
  141. sage/rings/asymptotic/asymptotic_ring.py +4858 -0
  142. sage/rings/asymptotic/asymptotics_multivariate_generating_functions.py +4153 -0
  143. sage/rings/asymptotic/growth_group.py +5373 -0
  144. sage/rings/asymptotic/growth_group_cartesian.py +1400 -0
  145. sage/rings/asymptotic/term_monoid.py +5237 -0
  146. sage/rings/function_field/all__sagemath_symbolics.py +2 -0
  147. sage/rings/polynomial/all__sagemath_symbolics.py +1 -0
  148. sage/symbolic/all.py +15 -0
  149. sage/symbolic/assumptions.py +985 -0
  150. sage/symbolic/benchmark.py +93 -0
  151. sage/symbolic/callable.py +459 -0
  152. sage/symbolic/complexity_measures.py +35 -0
  153. sage/symbolic/constants.py +1287 -0
  154. sage/symbolic/expression_conversion_algebraic.py +310 -0
  155. sage/symbolic/expression_conversion_sympy.py +317 -0
  156. sage/symbolic/expression_conversions.py +1713 -0
  157. sage/symbolic/function_factory.py +355 -0
  158. sage/symbolic/integration/all.py +1 -0
  159. sage/symbolic/integration/external.py +270 -0
  160. sage/symbolic/integration/integral.py +1115 -0
  161. sage/symbolic/maxima_wrapper.py +162 -0
  162. sage/symbolic/operators.py +267 -0
  163. sage/symbolic/random_tests.py +462 -0
  164. sage/symbolic/relation.py +1907 -0
  165. sage/symbolic/ring.cpython-314t-x86_64-linux-musl.so +0 -0
  166. sage/symbolic/ring.pxd +5 -0
  167. sage/symbolic/ring.pyx +1396 -0
  168. sage/symbolic/subring.py +1025 -0
  169. sage/symbolic/symengine.py +19 -0
  170. sage/symbolic/tests.py +40 -0
  171. sage/symbolic/units.py +1470 -0
@@ -0,0 +1,765 @@
1
+ # sage_setup: distribution = sagemath-symbolics
2
+ r"""
3
+ Mandelbrot and Julia sets
4
+
5
+ Plots the Mandelbrot and Julia sets for general polynomial maps in the complex
6
+ plane.
7
+
8
+ The Mandelbrot set is the set of complex numbers `c` for which the map
9
+ `f_c(z)` does not diverge when iterated from `z = 0`. This set of complex
10
+ numbers can be visualized by plotting each value for `c` in the complex plane.
11
+ The Mandelbrot set is often an example of a fractal when plotted in the complex
12
+ plane. For general one parameter families of polynomials, the mandelbrot set
13
+ is the parameter values for which the orbits of all critical points remains
14
+ bounded.
15
+
16
+ The Julia set for a given parameter `c` is the set of complex numbers for which
17
+ the function `f_c(z)` is bounded under iteration.
18
+
19
+ AUTHORS:
20
+
21
+ - Ben Barros
22
+ """
23
+
24
+ #*****************************************************************************
25
+ # Copyright (C) 2017 BEN BARROS <bbarros@slu.edu>
26
+ #
27
+ # This program is free software: you can redistribute it and/or modify
28
+ # it under the terms of the GNU General Public License as published by
29
+ # the Free Software Foundation, either version 2 of the License, or
30
+ # (at your option) any later version.
31
+ # http://www.gnu.org/licenses/
32
+ #*****************************************************************************
33
+
34
+ from sage.misc.lazy_import import lazy_import
35
+ lazy_import("sage.plot.colors", "Color")
36
+ lazy_import("sage.repl.image", "Image")
37
+ from sage.functions.log import logb
38
+ from sage.functions.other import floor
39
+ from sage.rings.rational_field import QQ
40
+ from sage.rings.cc import CC
41
+ from sage.rings.complex_double import CDF
42
+ from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
43
+ from sage.schemes.projective.projective_space import ProjectiveSpace
44
+ from sage.misc.prandom import randint
45
+ from sage.calculus.var import var
46
+ from sage.rings.fraction_field import FractionField_generic
47
+ from sage.categories.function_fields import FunctionFields
48
+
49
+ lazy_import('sage.dynamics.arithmetic_dynamics.generic_ds', 'DynamicalSystem')
50
+ lazy_import('sage.dynamics.complex_dynamics.mandel_julia_helper', (
51
+ 'fast_mandelbrot_plot',
52
+ 'fast_external_ray',
53
+ 'convert_to_pixels',
54
+ 'get_line',
55
+ 'fast_julia_plot',
56
+ 'general_julia',
57
+ 'polynomial_mandelbrot',
58
+ 'julia_helper'
59
+ ))
60
+
61
+ EPS = 0.00001
62
+
63
+
64
+ def mandelbrot_plot(f=None, **kwds):
65
+ r"""
66
+ Plot of the Mandelbrot set for a one parameter family of polynomial maps.
67
+
68
+ The family `f_c(z)` must have parent ``R`` of the
69
+ form ``R.<z,c> = CC[]``.
70
+
71
+ REFERENCE:
72
+
73
+ [Dev2005]_
74
+
75
+ INPUT:
76
+
77
+ - ``f`` -- map (default: ``z^2 + c``); polynomial family used to
78
+ plot the Mandelbrot set
79
+
80
+ - ``parameter`` -- variable (default: ``c``); parameter variable
81
+ used to plot the Mandelbrot set
82
+
83
+ - ``x_center`` -- double (default: ``-1.0``); Real part of center
84
+ point
85
+
86
+ - ``y_center`` -- double (default: ``0.0``); Imaginary part of
87
+ center point
88
+
89
+ - ``image_width`` -- double (default: ``4.0``); width of image
90
+ in the complex plane
91
+
92
+ - ``max_iteration`` -- long (default: ``500``); maximum number of
93
+ iterations the map ``f_c(z)``
94
+
95
+ - ``pixel_count`` -- long (default: ``500``); side length of
96
+ image in number of pixels
97
+
98
+ - ``base_color`` -- RGB color (default: ``[40, 40, 40]``); color
99
+ used to determine the coloring of set
100
+
101
+ - ``level_sep`` -- long (default: 1); number of iterations
102
+ between each color level
103
+
104
+ - ``number_of_colors`` -- long (default: 30); number of colors
105
+ used to plot image
106
+
107
+ - ``interact`` -- boolean (default: ``False``); controls whether
108
+ plot will have interactive functionality
109
+
110
+ OUTPUT: 24-bit RGB image of the Mandelbrot set in the complex plane
111
+
112
+ EXAMPLES:
113
+
114
+ ::
115
+
116
+ sage: mandelbrot_plot() # needs sage.plot
117
+ 500x500px 24-bit RGB image
118
+
119
+ ::
120
+
121
+ sage: mandelbrot_plot(pixel_count=1000) # needs sage.plot
122
+ 1000x1000px 24-bit RGB image
123
+
124
+ ::
125
+
126
+ sage: mandelbrot_plot(x_center=-1.11, y_center=0.2283, # long time, needs sage.plot
127
+ ....: image_width=1/128, max_iteration=2000,
128
+ ....: number_of_colors=500, base_color=[40, 100, 100])
129
+ 500x500px 24-bit RGB image
130
+
131
+ To display an interactive plot of the Mandelbrot in the Notebook, set
132
+ ``interact`` to ``True``. (This is only implemented for ``z^2 + c``)::
133
+
134
+ sage: mandelbrot_plot(interact=True) # needs sage.plot
135
+ ...interactive(children=(FloatSlider(value=0.0, description='Real center', max=1.0, min=-1.0, step=1e-05),
136
+ FloatSlider(value=0.0, description='Imag center', max=1.0, min=-1.0, step=1e-05),
137
+ FloatSlider(value=4.0, description='Width', max=4.0, min=1e-05, step=1e-05),
138
+ IntSlider(value=500, description='Iterations', max=1000),
139
+ IntSlider(value=500, description='Pixels', max=1000, min=10),
140
+ IntSlider(value=1, description='Color sep', max=20, min=1),
141
+ IntSlider(value=30, description='# Colors', min=1),
142
+ ColorPicker(value='#ff6347', description='Base color'), Output()),
143
+ _dom_classes=('widget-interact',))
144
+
145
+ ::
146
+
147
+ sage: mandelbrot_plot(interact=True, x_center=-0.75, y_center=0.25, # needs sage.plot
148
+ ....: image_width=1/2, number_of_colors=75)
149
+ ...interactive(children=(FloatSlider(value=-0.75, description='Real center', max=1.0, min=-1.0, step=1e-05),
150
+ FloatSlider(value=0.25, description='Imag center', max=1.0, min=-1.0, step=1e-05),
151
+ FloatSlider(value=0.5, description='Width', max=4.0, min=1e-05, step=1e-05),
152
+ IntSlider(value=500, description='Iterations', max=1000),
153
+ IntSlider(value=500, description='Pixels', max=1000, min=10),
154
+ IntSlider(value=1, description='Color sep', max=20, min=1),
155
+ IntSlider(value=75, description='# Colors', min=1),
156
+ ColorPicker(value='#ff6347', description='Base color'), Output()),
157
+ _dom_classes=('widget-interact',))
158
+
159
+ Polynomial maps can be defined over a multivariate polynomial ring or a
160
+ univariate polynomial ring tower::
161
+
162
+ sage: R.<z,c> = CC[]
163
+ sage: f = z^2 + c
164
+ sage: mandelbrot_plot(f) # needs sage.plot
165
+ 500x500px 24-bit RGB image
166
+
167
+ ::
168
+
169
+ sage: B.<c> = CC[]
170
+ sage: R.<z> = B[]
171
+ sage: f = z^5 + c
172
+ sage: mandelbrot_plot(f) # long time # needs sage.plot
173
+ 500x500px 24-bit RGB image
174
+
175
+ When the polynomial is defined over a multivariate polynomial ring it is
176
+ necessary to specify the parameter variable (default parameter is ``c``)::
177
+
178
+ sage: R.<a,b> = CC[]
179
+ sage: f = a^2 + b^3
180
+ sage: mandelbrot_plot(f, parameter=b) # long time # needs sage.plot
181
+ 500x500px 24-bit RGB image
182
+
183
+ Interact functionality is not implemented for general polynomial maps::
184
+
185
+ sage: R.<z,c> = CC[]
186
+ sage: f = z^3 + c
187
+ sage: mandelbrot_plot(f, interact=True) # needs sage.plot
188
+ Traceback (most recent call last):
189
+ ...
190
+ NotImplementedError: interact only implemented for z^2 + c
191
+ """
192
+ parameter = kwds.pop("parameter", None)
193
+ x_center = kwds.pop("x_center", 0.0)
194
+ y_center = kwds.pop("y_center", 0.0)
195
+ image_width = kwds.pop("image_width", 4.0)
196
+ max_iteration = kwds.pop("max_iteration", None)
197
+ pixel_count = kwds.pop("pixel_count", 500)
198
+ level_sep = kwds.pop("level_sep", 1)
199
+ number_of_colors = kwds.pop("number_of_colors", 30)
200
+ interacts = kwds.pop("interact", False)
201
+ base_color = kwds.pop("base_color", Color('tomato'))
202
+ # Check if user specified maximum number of iterations
203
+ given_iterations = True
204
+ if max_iteration is None:
205
+ # Set default to 500 for z^2 + c map
206
+ max_iteration = 500
207
+ given_iterations = False
208
+
209
+ from ipywidgets.widgets import FloatSlider, IntSlider, ColorPicker, interact
210
+ widgets = dict(
211
+ x_center=FloatSlider(min=-1.0, max=1.0, step=EPS,
212
+ value=x_center, description="Real center"),
213
+ y_center=FloatSlider(min=-1.0, max=1.0, step=EPS,
214
+ value=y_center, description="Imag center"),
215
+ image_width=FloatSlider(min=EPS, max=4.0, step=EPS,
216
+ value=image_width, description='Width'),
217
+ max_iteration=IntSlider(min=0, max=1000,
218
+ value=max_iteration, description='Iterations'),
219
+ pixel_count=IntSlider(min=10, max=1000,
220
+ value=pixel_count, description='Pixels'),
221
+ level_sep=IntSlider(min=1, max=20,
222
+ value=level_sep, description="Color sep"),
223
+ color_num=IntSlider(min=1, max=100,
224
+ value=number_of_colors, description="# Colors"),
225
+ base_color=ColorPicker(value=Color(base_color).html_color(),
226
+ description="Base color"),
227
+ )
228
+
229
+ if f is None:
230
+ # Quadratic map f = z^2 + c
231
+
232
+ if interacts:
233
+ return interact(**widgets).widget(fast_mandelbrot_plot)
234
+
235
+ else:
236
+ return fast_mandelbrot_plot(x_center, y_center, image_width,
237
+ max_iteration, pixel_count, level_sep, number_of_colors,
238
+ base_color)
239
+
240
+ else:
241
+ if parameter is None:
242
+ c = var('c')
243
+ parameter = c
244
+
245
+ P = f.parent()
246
+
247
+ if P.base_ring() is CC or P.base_ring() is CDF:
248
+ if isinstance(P, FractionField_generic):
249
+ raise NotImplementedError("coefficients must be polynomials in the parameter")
250
+ gen_list = list(P.gens())
251
+ parameter = gen_list.pop(gen_list.index(parameter))
252
+ variable = gen_list.pop()
253
+
254
+ elif P.base_ring().base_ring() is CC or P.base_ring().base_ring() is CDF:
255
+ if isinstance(P.base_ring(), FractionField_generic):
256
+ raise NotImplementedError("coefficients must be polynomials in the parameter")
257
+ phi = P.flattening_morphism()
258
+ f = phi(f)
259
+ gen_list = list(f.parent().gens())
260
+ parameter = gen_list.pop(gen_list.index(parameter))
261
+ variable = gen_list.pop()
262
+
263
+ elif P.base_ring() in FunctionFields():
264
+ raise NotImplementedError("coefficients must be polynomials in the parameter")
265
+
266
+ else:
267
+ raise ValueError("base ring must be a complex field")
268
+
269
+ if f == variable**2 + parameter:
270
+ # Quadratic map f = z^2 + c
271
+ if interacts:
272
+ return interact(**widgets).widget(fast_mandelbrot_plot)
273
+
274
+ else:
275
+ return fast_mandelbrot_plot(x_center, y_center, image_width,
276
+ max_iteration, pixel_count, level_sep, number_of_colors,
277
+ base_color)
278
+ else:
279
+ if interacts:
280
+ raise NotImplementedError("interact only implemented for z^2 + c")
281
+ else:
282
+ # Set default of max_iteration to 50 for general polynomial maps
283
+ # This prevents the function from being very slow by default
284
+ if not given_iterations:
285
+ max_iteration = 50
286
+
287
+ # Mandelbrot of General Polynomial Map
288
+ return polynomial_mandelbrot(f, parameter, x_center, y_center,
289
+ image_width, max_iteration, pixel_count, level_sep,
290
+ number_of_colors, base_color)
291
+
292
+
293
+ def external_ray(theta, **kwds):
294
+ r"""
295
+ Draws the external ray(s) of a given angle (or list of angles)
296
+ by connecting a finite number of points that were approximated using
297
+ Newton's method. The algorithm used is described in a paper by
298
+ Tomoki Kawahira.
299
+
300
+ REFERENCE:
301
+
302
+ [Kaw2009]_
303
+
304
+ INPUT:
305
+
306
+ - ``theta`` -- double or list of doubles, angles between 0 and 1 inclusive
307
+
308
+ kwds:
309
+
310
+ - ``image`` -- 24-bit RGB image (default: ``None``); user specified
311
+ image of Mandelbrot set
312
+
313
+ - ``D`` -- long (default: ``25``); depth of the approximation.
314
+ As ``D`` increases, the external ray gets closer to the boundary of the
315
+ Mandelbrot set. If the ray doesn't reach the boundary of the Mandelbrot
316
+ set, increase ``D``.
317
+
318
+ - ``S`` -- long (default: ``10``); sharpness of the approximation.
319
+ Adjusts the number of points used to approximate the external ray (number
320
+ of points is equal to ``S*D``). If ray looks jagged, increase ``S``.
321
+
322
+ - ``R`` -- long (default: ``100``); radial parameter. If ``R`` is
323
+ large, the external ray reaches sufficiently close to infinity. If ``R`` is
324
+ too small, Newton's method may not converge to the correct ray.
325
+
326
+ - ``prec`` -- long (default: ``300``); specifies the bits of
327
+ precision used by the Complex Field when using Newton's method to compute
328
+ points on the external ray
329
+
330
+ - ``ray_color`` -- RGB color (default: ``[255, 255, 255]``) color
331
+ of the external ray(s)
332
+
333
+ OUTPUT: 24-bit RGB image of external ray(s) on the Mandelbrot set
334
+
335
+ EXAMPLES::
336
+
337
+ sage: external_ray(1/3) # needs sage.plot
338
+ 500x500px 24-bit RGB image
339
+
340
+ ::
341
+
342
+ sage: external_ray(0.6, ray_color=[255, 0, 0]) # needs sage.plot
343
+ 500x500px 24-bit RGB image
344
+
345
+ ::
346
+
347
+ sage: external_ray([0, 0.2, 0.4, 0.7]) # needs sage.plot
348
+ 500x500px 24-bit RGB image
349
+
350
+ ::
351
+
352
+ sage: external_ray([i/5 for i in range(1,5)]) # needs sage.plot
353
+ 500x500px 24-bit RGB image
354
+
355
+ WARNING:
356
+
357
+ If you are passing in an image, make sure you specify
358
+ which parameters to use when drawing the external ray.
359
+ For example, the following is incorrect::
360
+
361
+ sage: M = mandelbrot_plot(x_center=0) # not tested # needs sage.plot
362
+ sage: external_ray(5/7, image=M) # not tested # needs sage.plot
363
+ 500x500px 24-bit RGB image
364
+
365
+ To get the correct external ray, we adjust our parameters::
366
+
367
+ sage: M = mandelbrot_plot(x_center=0) # needs sage.plot
368
+ sage: external_ray(5/7, x_center=0, image=M) # needs sage.plot
369
+ 500x500px 24-bit RGB image
370
+
371
+ .. TODO::
372
+
373
+ The ``copy()`` function for bitmap images needs to be implemented
374
+ in Sage.
375
+ """
376
+ x_0 = kwds.get("x_center", -1)
377
+ y_0 = kwds.get("y_center", 0)
378
+ plot_width = kwds.get("image_width", 4)
379
+ pixel_width = kwds.get("pixel_count", 500)
380
+ depth = kwds.get("D", 25)
381
+ sharpness = kwds.get("S", 10)
382
+ radial_parameter = kwds.get("R", 100)
383
+ precision = kwds.get("prec", 300)
384
+ precision = max(precision, -logb(pixel_width * 0.001, 2).round() + 10)
385
+ ray_color = kwds.get("ray_color", [255] * 3)
386
+ image = kwds.get("image", None)
387
+ if image is None:
388
+ image = mandelbrot_plot(x_center=x_0, **kwds)
389
+
390
+ # Make a copy of the bitmap image.
391
+ old_pixel = image.pixels()
392
+ M = Image('RGB', (pixel_width, pixel_width))
393
+ pixel = M.pixels()
394
+ for i in range(pixel_width):
395
+ for j in range(pixel_width):
396
+ pixel[i, j] = old_pixel[i, j]
397
+
398
+ # Make sure that theta is a list so loop below works
399
+ if not isinstance(theta, list):
400
+ theta = [theta]
401
+
402
+ # Check if theta is in the interval [0,1]
403
+ for angle in theta:
404
+ if angle < 0 or angle > 1:
405
+ raise ValueError("values for theta must be in "
406
+ "the closed interval [0,1].")
407
+
408
+ # Loop through each value for theta in list and plot the external ray.
409
+ for angle in theta:
410
+ E = fast_external_ray(angle, D=depth, S=sharpness, R=radial_parameter,
411
+ prec=precision, image_width=plot_width,
412
+ pixel_count=pixel_width)
413
+
414
+ # Convert points to pixel coordinates.
415
+ pixel_list = convert_to_pixels(E, x_0, y_0, plot_width, pixel_width)
416
+
417
+ # Find the pixels between points in pixel_list.
418
+ extra_points = []
419
+ for i in range(len(pixel_list) - 1):
420
+ if min(pixel_list[i + 1]) >= 0 and max(pixel_list[i + 1]) < pixel_width:
421
+ for j in get_line(pixel_list[i], pixel_list[i + 1]):
422
+ extra_points.append(j)
423
+
424
+ # Add these points to pixel_list to fill in gaps in the ray.
425
+ pixel_list += extra_points
426
+
427
+ # Remove duplicates from list.
428
+ pixel_list = list(set(pixel_list))
429
+
430
+ # Check if point is in window and if it is, plot it on the image to
431
+ # create an external ray.
432
+ for k in pixel_list:
433
+ if max(k) < pixel_width and min(k) >= 0:
434
+ pixel[int(k[0]), int(k[1])] = tuple(ray_color)
435
+ return M
436
+
437
+
438
+ def kneading_sequence(theta):
439
+ r"""
440
+ Determines the kneading sequence for an angle theta in RR/ZZ which
441
+ is periodic under doubling. We use the definition for the kneading
442
+ sequence given in Definition 3.2 of [LS1994]_.
443
+
444
+ INPUT:
445
+
446
+ - ``theta`` -- a rational number with odd denominator
447
+
448
+ OUTPUT: string representing the kneading sequence of theta in RR/ZZ
449
+
450
+ REFERENCES:
451
+
452
+ [LS1994]_
453
+
454
+ EXAMPLES::
455
+
456
+ sage: kneading_sequence(0)
457
+ '*'
458
+
459
+ ::
460
+
461
+ sage: kneading_sequence(1/3)
462
+ '1*'
463
+
464
+ Since 1/3 and 7/3 are the same in RR/ZZ, they have the same kneading sequence::
465
+
466
+ sage: kneading_sequence(7/3)
467
+ '1*'
468
+
469
+ We can also use (finite) decimal inputs, as long as the denominator in reduced form is odd::
470
+
471
+ sage: kneading_sequence(1.2)
472
+ '110*'
473
+
474
+ Since rationals with even denominator are not periodic under doubling, we have not implemented kneading sequences for such rationals::
475
+
476
+ sage: kneading_sequence(1/4)
477
+ Traceback (most recent call last):
478
+ ...
479
+ ValueError: input must be a rational number with odd denominator
480
+ """
481
+
482
+ if theta not in QQ:
483
+ raise TypeError('input must be a rational number with odd denominator')
484
+ elif QQ(theta).valuation(2) < 0:
485
+ raise ValueError('input must be a rational number with odd denominator')
486
+ else:
487
+ theta = QQ(theta)
488
+ theta = theta - floor(theta)
489
+ KS = []
490
+ not_done = True
491
+ left = theta/2
492
+ right = (theta + 1)/2
493
+ y = theta
494
+ while not_done:
495
+ if ((y < left) or (y > right)):
496
+ KS.append('0')
497
+ elif ((y > left) and (y < right)):
498
+ KS.append('1')
499
+ else:
500
+ not_done = False
501
+ y = 2*y - floor(2*y)
502
+ KS_str = ''.join(KS) + '*'
503
+ return KS_str
504
+
505
+
506
+ def julia_plot(f=None, **kwds):
507
+ r"""
508
+ Plots the Julia set of a given polynomial ``f``. Users can specify whether
509
+ they would like to display the Mandelbrot side by side with the Julia set
510
+ with the ``mandelbrot`` argument. If ``f`` is not specified, this method
511
+ defaults to `f(z) = z^2-1`.
512
+
513
+ The Julia set of a polynomial ``f`` is the set of complex numbers `z` for
514
+ which the function `f(z)` is bounded under iteration. The Julia set can
515
+ be visualized by plotting each point in the set in the complex plane.
516
+ Julia sets are examples of fractals when plotted in the complex plane.
517
+
518
+ ALGORITHM:
519
+
520
+ Let `R_c = \bigl(1 + \sqrt{1 + 4|c|}\bigr)/2` if the polynomial is of the
521
+ form `f(z) = z^2 + c`; otherwise, let `R_c = 2`.
522
+ For every `p \in \mathbb{C}`, if `|f^{k}(p)| > R_c` for some `k \geq 0`,
523
+ then `f^{n}(p) \to \infty`. Let `N` be the maximum number of iterations.
524
+ Compute the first `N` points on the orbit of `p` under `f`. If for
525
+ any `k < N`, `|f^{k}(p)| > R_c`, we stop the iteration and assign a color
526
+ to the point `p` based on how quickly `p` escaped to infinity under
527
+ iteration of `f`. If `|f^{i}(p)| \leq R_c` for all `i \leq N`, we assume
528
+ `p` is in the Julia set and assign the point `p` the color black.
529
+
530
+ INPUT:
531
+
532
+ - ``f`` -- input polynomial (default: ``z^2 - 1``)
533
+
534
+ - ``period`` -- list (default: ``None``); returns the Julia set
535
+ for a random `c` value with the given (formal) cycle structure
536
+
537
+ - ``mandelbrot`` -- boolean (default: ``True``); when set to
538
+ ``True``, an image of the Mandelbrot set is appended to the right of the
539
+ Julia set
540
+
541
+ - ``point_color`` -- RGB color (default: ``'tomato'``);
542
+ color of the point `c` in the Mandelbrot set (any valid input for Color)
543
+
544
+ - ``x_center`` -- double (default: ``-1.0``); real part
545
+ of center point
546
+
547
+ - ``y_center`` -- double (default: ``0.0``); imaginary part
548
+ of center point
549
+
550
+ - ``image_width`` -- double (default: ``4.0``); width of image
551
+ in the complex plane
552
+
553
+ - ``max_iteration`` -- long (default: ``500``); maximum number
554
+ of iterations the map `f(z)`
555
+
556
+ - ``pixel_count`` -- long (default: ``500``); side length of
557
+ image in number of pixels
558
+
559
+ - ``base_color`` -- hex color (default: ``'steelblue'``); color
560
+ used to determine the coloring of set (any valid input for Color)
561
+
562
+ - ``level_sep`` -- long (default: 1); number of iterations
563
+ between each color level
564
+
565
+ - ``number_of_colors`` -- long (default: 30); number of colors
566
+ used to plot image
567
+
568
+ - ``interact`` -- boolean (default: ``False``); controls whether
569
+ plot will have interactive functionality
570
+
571
+ OUTPUT: 24-bit RGB image of the Julia set in the complex plane
572
+
573
+ .. TODO::
574
+
575
+ Implement the side-by-side Mandelbrot-Julia plots for general one-parameter families
576
+ of polynomials.
577
+
578
+ EXAMPLES:
579
+
580
+ The default ``f`` is `z^2 - 1`::
581
+
582
+ sage: julia_plot() # needs sage.plot
583
+ 1001x500px 24-bit RGB image
584
+
585
+ To display only the Julia set, set ``mandelbrot`` to ``False``::
586
+
587
+ sage: julia_plot(mandelbrot=False) # needs sage.plot
588
+ 500x500px 24-bit RGB image
589
+
590
+ ::
591
+
592
+ sage: R.<z> = CC[]
593
+ sage: f = z^3 - z + 1
594
+ sage: julia_plot(f) # long time # needs sage.plot
595
+ 500x500px 24-bit RGB image
596
+
597
+ To display an interactive plot of the Julia set in the Notebook,
598
+ set ``interact`` to ``True``. (This is only implemented for polynomials of
599
+ the form ``f = z^2 + c``)::
600
+
601
+ sage: julia_plot(interact=True) # needs sage.plot
602
+ ...interactive(children=(FloatSlider(value=-1.0, description='Real c'...
603
+
604
+ ::
605
+
606
+ sage: R.<z> = CC[]
607
+ sage: f = z^2 + 1/2
608
+ sage: julia_plot(f, interact=True) # needs sage.plot
609
+ ...interactive(children=(FloatSlider(value=0.5, description='Real c'...
610
+
611
+ To return the Julia set of a random `c` value with (formal) cycle structure
612
+ `(2,3)`, set ``period = [2,3]``::
613
+
614
+ sage: julia_plot(period=[2,3]) # needs sage.plot
615
+ 1001x500px 24-bit RGB image
616
+
617
+ To return all of the Julia sets of `c` values with (formal) cycle structure
618
+ `(2,3)`::
619
+
620
+ sage: period = [2,3] # not tested
621
+ ....: R.<c> = QQ[]
622
+ ....: P.<x,y> = ProjectiveSpace(R,1)
623
+ ....: f = DynamicalSystem([x^2+c*y^2, y^2])
624
+ ....: L = f.dynatomic_polynomial(period).subs({x:0,y:1}).roots(ring=CC)
625
+ ....: c_values = [k[0] for k in L]
626
+ ....: for c in c_values:
627
+ ....: julia_plot(c)
628
+
629
+ Polynomial maps can be defined over a polynomial ring or a fraction field,
630
+ so long as ``f`` is polynomial::
631
+
632
+ sage: R.<z> = CC[]
633
+ sage: f = z^2 - 1
634
+ sage: julia_plot(f) # needs sage.plot
635
+ 1001x500px 24-bit RGB image
636
+
637
+ ::
638
+
639
+ sage: R.<z> = CC[]
640
+ sage: K = R.fraction_field(); z = K.gen()
641
+ sage: f = z^2 - 1
642
+ sage: julia_plot(f) # needs sage.plot
643
+ 1001x500px 24-bit RGB image
644
+
645
+ Interact functionality is not implemented if the polynomial is not of the
646
+ form `f = z^2 + c`::
647
+
648
+ sage: R.<z> = CC[]
649
+ sage: f = z^3 + 1
650
+ sage: julia_plot(f, interact=True) # needs sage.plot
651
+ Traceback (most recent call last):
652
+ ...
653
+ NotImplementedError: The interactive plot is only implemented for ...
654
+ """
655
+
656
+ # extract keyword arguments
657
+ period = kwds.pop("period", None)
658
+ mandelbrot = kwds.pop("mandelbrot", True)
659
+ point_color = kwds.pop("point_color", 'tomato')
660
+ x_center = kwds.pop("x_center", 0.0)
661
+ y_center = kwds.pop("y_center", 0.0)
662
+ image_width = kwds.pop("image_width", 4.0)
663
+ max_iteration = kwds.pop("max_iteration", 500)
664
+ pixel_count = kwds.pop("pixel_count", 500)
665
+ base_color = kwds.pop("base_color", 'steelblue')
666
+ level_sep = kwds.pop("level_sep", 1)
667
+ number_of_colors = kwds.pop("number_of_colors", 30)
668
+ interacts = kwds.pop("interact", False)
669
+
670
+ f_is_default_after_all = None
671
+
672
+ if period: # pick a random c with the specified period
673
+ R = PolynomialRing(CC, 'c')
674
+ c = R.gen()
675
+ x, y = ProjectiveSpace(R, 1, 'x,y').gens()
676
+ F = DynamicalSystem([x**2 + c * y**2, y**2])
677
+ L = F.dynatomic_polynomial(period).subs({x: 0, y: 1}).roots(ring=CC)
678
+ c = L[randint(0, len(L) - 1)][0]
679
+
680
+ base_color = Color(base_color)
681
+ point_color = Color(point_color)
682
+
683
+ EPS = 0.00001
684
+
685
+ if f is not None and period is None: # f user-specified and no period given
686
+
687
+ # try to coerce f to live in a polynomial ring
688
+ S = PolynomialRing(CC, names='z')
689
+ z = S.gen()
690
+ try:
691
+ f_poly = S(f)
692
+ except TypeError:
693
+ R = f.parent()
694
+ if not (R.is_integral_domain() and
695
+ (CC.is_subring(R) or CDF.is_subring(R))):
696
+ raise ValueError('given `f` must be a complex polynomial')
697
+ raise NotImplementedError(
698
+ 'Julia sets not implemented for rational functions')
699
+
700
+ if (f_poly - z*z) in CC: # f is specified and of the form z^2 + c.
701
+ f_is_default_after_all = True
702
+ c = f_poly - z*z
703
+ else: # f is specified and not of the form z^2 + c
704
+ if interacts:
705
+ raise NotImplementedError(
706
+ "The interactive plot is only implemented for "
707
+ "polynomials of the form f = z^2 + c."
708
+ )
709
+ else:
710
+ return general_julia(f_poly, x_center, y_center,
711
+ image_width, max_iteration,
712
+ pixel_count, level_sep,
713
+ number_of_colors, base_color)
714
+
715
+ # otherwise we can use fast_julia_plot for z^2 + c
716
+ if f_is_default_after_all or f is None or period is not None:
717
+
718
+ # specify default c = -1 value if f and period were not specified
719
+ if not f_is_default_after_all and period is None:
720
+ c = -1
721
+
722
+ c = CC(c)
723
+ c_real = c.real()
724
+ c_imag = c.imag()
725
+
726
+ if interacts: # set widgets
727
+ from ipywidgets.widgets import FloatSlider, IntSlider, \
728
+ ColorPicker, interact
729
+ widgets = dict(
730
+ c_real=FloatSlider(min=-2.0, max=2.0, step=EPS,
731
+ value=c_real, description="Real c"),
732
+ c_imag=FloatSlider(min=-2.0, max=2.0, step=EPS,
733
+ value=c_imag, description="Imag c"),
734
+ x_center=FloatSlider(min=-1.0, max=1.0, step=EPS,
735
+ value=x_center, description="Real center"),
736
+ y_center=FloatSlider(min=-1.0, max=1.0, step=EPS,
737
+ value=y_center, description="Imag center"),
738
+ image_width=FloatSlider(min=EPS, max=4.0, step=EPS,
739
+ value=image_width, description='Width'),
740
+ max_iteration=IntSlider(min=0, max=1000,
741
+ value=max_iteration, description='Iterations'),
742
+ pixel_count=IntSlider(min=10, max=1000,
743
+ value=pixel_count, description='Pixels'),
744
+ level_sep=IntSlider(min=1, max=20,
745
+ value=level_sep, description="Color sep"),
746
+ color_num=IntSlider(min=1, max=100,
747
+ value=number_of_colors, description="# Colors"),
748
+ base_color=ColorPicker(value=base_color.html_color(),
749
+ description="Base color"),
750
+ )
751
+ if mandelbrot:
752
+ widgets["point_color"] = ColorPicker(value=point_color.html_color(),
753
+ description="Point color")
754
+ return interact(**widgets).widget(julia_helper)
755
+ else:
756
+ return interact(**widgets).widget(fast_julia_plot)
757
+ elif mandelbrot: # non-interactive with mandelbrot
758
+ return julia_helper(c_real, c_imag, x_center, y_center,
759
+ image_width, max_iteration, pixel_count,
760
+ level_sep, number_of_colors, base_color,
761
+ point_color)
762
+ else: # non-interactive without mandelbrot
763
+ return fast_julia_plot(c_real, c_imag, x_center, y_center,
764
+ image_width, max_iteration, pixel_count,
765
+ level_sep, number_of_colors, base_color)