passagemath-schemes 10.6.38__cp314-cp314t-macosx_13_0_arm64.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-schemes might be problematic. Click here for more details.
- passagemath_schemes/.dylibs/libflint.21.0.dylib +0 -0
- passagemath_schemes/.dylibs/libgmp.10.dylib +0 -0
- passagemath_schemes/.dylibs/libgmpxx.4.dylib +0 -0
- passagemath_schemes/.dylibs/libmpfr.6.dylib +0 -0
- passagemath_schemes/__init__.py +3 -0
- passagemath_schemes-10.6.38.dist-info/METADATA +204 -0
- passagemath_schemes-10.6.38.dist-info/METADATA.bak +205 -0
- passagemath_schemes-10.6.38.dist-info/RECORD +314 -0
- passagemath_schemes-10.6.38.dist-info/WHEEL +6 -0
- passagemath_schemes-10.6.38.dist-info/top_level.txt +3 -0
- sage/all__sagemath_schemes.py +23 -0
- sage/databases/all__sagemath_schemes.py +7 -0
- sage/databases/cremona.py +1723 -0
- sage/dynamics/all__sagemath_schemes.py +2 -0
- sage/dynamics/arithmetic_dynamics/affine_ds.py +1083 -0
- sage/dynamics/arithmetic_dynamics/all.py +14 -0
- sage/dynamics/arithmetic_dynamics/berkovich_ds.py +1101 -0
- sage/dynamics/arithmetic_dynamics/dynamical_semigroup.py +1543 -0
- sage/dynamics/arithmetic_dynamics/endPN_automorphism_group.py +2426 -0
- sage/dynamics/arithmetic_dynamics/endPN_minimal_model.py +1169 -0
- sage/dynamics/arithmetic_dynamics/generic_ds.py +663 -0
- sage/dynamics/arithmetic_dynamics/product_projective_ds.py +339 -0
- sage/dynamics/arithmetic_dynamics/projective_ds.py +9558 -0
- sage/dynamics/arithmetic_dynamics/projective_ds_helper.cpython-314t-darwin.so +0 -0
- sage/dynamics/arithmetic_dynamics/projective_ds_helper.pyx +301 -0
- sage/dynamics/arithmetic_dynamics/wehlerK3.py +2576 -0
- sage/lfunctions/all.py +18 -0
- sage/lfunctions/dokchitser.py +745 -0
- sage/lfunctions/pari.py +818 -0
- sage/lfunctions/zero_sums.cpython-314t-darwin.so +0 -0
- sage/lfunctions/zero_sums.pyx +1847 -0
- sage/modular/abvar/abvar.py +5135 -0
- sage/modular/abvar/abvar_ambient_jacobian.py +413 -0
- sage/modular/abvar/abvar_newform.py +244 -0
- sage/modular/abvar/all.py +8 -0
- sage/modular/abvar/constructor.py +186 -0
- sage/modular/abvar/cuspidal_subgroup.py +371 -0
- sage/modular/abvar/finite_subgroup.py +896 -0
- sage/modular/abvar/homology.py +720 -0
- sage/modular/abvar/homspace.py +998 -0
- sage/modular/abvar/lseries.py +415 -0
- sage/modular/abvar/morphism.py +935 -0
- sage/modular/abvar/torsion_point.py +274 -0
- sage/modular/abvar/torsion_subgroup.py +740 -0
- sage/modular/all.py +43 -0
- sage/modular/arithgroup/all.py +20 -0
- sage/modular/arithgroup/arithgroup_element.cpython-314t-darwin.so +0 -0
- sage/modular/arithgroup/arithgroup_element.pyx +474 -0
- sage/modular/arithgroup/arithgroup_generic.py +1402 -0
- sage/modular/arithgroup/arithgroup_perm.py +2692 -0
- sage/modular/arithgroup/congroup.cpython-314t-darwin.so +0 -0
- sage/modular/arithgroup/congroup.pyx +334 -0
- sage/modular/arithgroup/congroup_gamma.py +363 -0
- sage/modular/arithgroup/congroup_gamma0.py +692 -0
- sage/modular/arithgroup/congroup_gamma1.py +653 -0
- sage/modular/arithgroup/congroup_gammaH.py +1469 -0
- sage/modular/arithgroup/congroup_generic.py +628 -0
- sage/modular/arithgroup/congroup_sl2z.py +267 -0
- sage/modular/arithgroup/farey_symbol.cpython-314t-darwin.so +0 -0
- sage/modular/arithgroup/farey_symbol.pyx +1066 -0
- sage/modular/arithgroup/tests.py +418 -0
- sage/modular/btquotients/all.py +4 -0
- sage/modular/btquotients/btquotient.py +3753 -0
- sage/modular/btquotients/pautomorphicform.py +2570 -0
- sage/modular/buzzard.py +100 -0
- sage/modular/congroup.py +29 -0
- sage/modular/congroup_element.py +13 -0
- sage/modular/cusps.py +1109 -0
- sage/modular/cusps_nf.py +1270 -0
- sage/modular/dims.py +569 -0
- sage/modular/dirichlet.py +3310 -0
- sage/modular/drinfeld_modform/all.py +2 -0
- sage/modular/drinfeld_modform/element.py +446 -0
- sage/modular/drinfeld_modform/ring.py +773 -0
- sage/modular/drinfeld_modform/tutorial.py +236 -0
- sage/modular/etaproducts.py +1065 -0
- sage/modular/hecke/algebra.py +746 -0
- sage/modular/hecke/all.py +20 -0
- sage/modular/hecke/ambient_module.py +1019 -0
- sage/modular/hecke/degenmap.py +119 -0
- sage/modular/hecke/element.py +325 -0
- sage/modular/hecke/hecke_operator.py +780 -0
- sage/modular/hecke/homspace.py +206 -0
- sage/modular/hecke/module.py +1767 -0
- sage/modular/hecke/morphism.py +174 -0
- sage/modular/hecke/submodule.py +989 -0
- sage/modular/hypergeometric_misc.cpython-314t-darwin.so +0 -0
- sage/modular/hypergeometric_misc.pxd +4 -0
- sage/modular/hypergeometric_misc.pyx +166 -0
- sage/modular/hypergeometric_motive.py +2017 -0
- sage/modular/local_comp/all.py +2 -0
- sage/modular/local_comp/liftings.py +292 -0
- sage/modular/local_comp/local_comp.py +1071 -0
- sage/modular/local_comp/smoothchar.py +1825 -0
- sage/modular/local_comp/type_space.py +748 -0
- sage/modular/modform/all.py +30 -0
- sage/modular/modform/ambient.py +815 -0
- sage/modular/modform/ambient_R.py +177 -0
- sage/modular/modform/ambient_eps.py +306 -0
- sage/modular/modform/ambient_g0.py +124 -0
- sage/modular/modform/ambient_g1.py +204 -0
- sage/modular/modform/constructor.py +545 -0
- sage/modular/modform/cuspidal_submodule.py +708 -0
- sage/modular/modform/defaults.py +14 -0
- sage/modular/modform/eis_series.py +505 -0
- sage/modular/modform/eisenstein_submodule.py +663 -0
- sage/modular/modform/element.py +4131 -0
- sage/modular/modform/find_generators.py +59 -0
- sage/modular/modform/half_integral.py +154 -0
- sage/modular/modform/hecke_operator_on_qexp.py +247 -0
- sage/modular/modform/j_invariant.py +47 -0
- sage/modular/modform/l_series_gross_zagier.py +133 -0
- sage/modular/modform/l_series_gross_zagier_coeffs.cpython-314t-darwin.so +0 -0
- sage/modular/modform/l_series_gross_zagier_coeffs.pyx +177 -0
- sage/modular/modform/notes.py +45 -0
- sage/modular/modform/numerical.py +514 -0
- sage/modular/modform/periods.py +14 -0
- sage/modular/modform/ring.py +1257 -0
- sage/modular/modform/space.py +1860 -0
- sage/modular/modform/submodule.py +118 -0
- sage/modular/modform/tests.py +64 -0
- sage/modular/modform/theta.py +110 -0
- sage/modular/modform/vm_basis.py +381 -0
- sage/modular/modform/weight1.py +220 -0
- sage/modular/modform_hecketriangle/abstract_ring.py +1932 -0
- sage/modular/modform_hecketriangle/abstract_space.py +2528 -0
- sage/modular/modform_hecketriangle/all.py +30 -0
- sage/modular/modform_hecketriangle/analytic_type.py +590 -0
- sage/modular/modform_hecketriangle/constructor.py +416 -0
- sage/modular/modform_hecketriangle/element.py +351 -0
- sage/modular/modform_hecketriangle/functors.py +752 -0
- sage/modular/modform_hecketriangle/graded_ring.py +541 -0
- sage/modular/modform_hecketriangle/graded_ring_element.py +2225 -0
- sage/modular/modform_hecketriangle/hecke_triangle_group_element.py +3352 -0
- sage/modular/modform_hecketriangle/hecke_triangle_groups.py +1432 -0
- sage/modular/modform_hecketriangle/readme.py +1214 -0
- sage/modular/modform_hecketriangle/series_constructor.py +580 -0
- sage/modular/modform_hecketriangle/space.py +1037 -0
- sage/modular/modform_hecketriangle/subspace.py +423 -0
- sage/modular/modsym/all.py +17 -0
- sage/modular/modsym/ambient.py +3846 -0
- sage/modular/modsym/boundary.py +1420 -0
- sage/modular/modsym/element.py +336 -0
- sage/modular/modsym/g1list.py +178 -0
- sage/modular/modsym/ghlist.py +182 -0
- sage/modular/modsym/hecke_operator.py +73 -0
- sage/modular/modsym/manin_symbol.cpython-314t-darwin.so +0 -0
- sage/modular/modsym/manin_symbol.pxd +5 -0
- sage/modular/modsym/manin_symbol.pyx +497 -0
- sage/modular/modsym/manin_symbol_list.py +1295 -0
- sage/modular/modsym/modsym.py +400 -0
- sage/modular/modsym/modular_symbols.py +384 -0
- sage/modular/modsym/p1list.cpython-314t-darwin.so +0 -0
- sage/modular/modsym/p1list.pxd +29 -0
- sage/modular/modsym/p1list.pyx +1372 -0
- sage/modular/modsym/p1list_nf.py +1241 -0
- sage/modular/modsym/relation_matrix.py +591 -0
- sage/modular/modsym/relation_matrix_pyx.cpython-314t-darwin.so +0 -0
- sage/modular/modsym/relation_matrix_pyx.pyx +108 -0
- sage/modular/modsym/space.py +2468 -0
- sage/modular/modsym/subspace.py +455 -0
- sage/modular/modsym/tests.py +375 -0
- sage/modular/multiple_zeta.py +2632 -0
- sage/modular/multiple_zeta_F_algebra.py +786 -0
- sage/modular/overconvergent/all.py +6 -0
- sage/modular/overconvergent/genus0.py +1878 -0
- sage/modular/overconvergent/hecke_series.py +1187 -0
- sage/modular/overconvergent/weightspace.py +778 -0
- sage/modular/pollack_stevens/all.py +4 -0
- sage/modular/pollack_stevens/distributions.py +874 -0
- sage/modular/pollack_stevens/fund_domain.py +1572 -0
- sage/modular/pollack_stevens/manin_map.py +859 -0
- sage/modular/pollack_stevens/modsym.py +1593 -0
- sage/modular/pollack_stevens/padic_lseries.py +417 -0
- sage/modular/pollack_stevens/sigma0.py +534 -0
- sage/modular/pollack_stevens/space.py +1076 -0
- sage/modular/quasimodform/all.py +3 -0
- sage/modular/quasimodform/element.py +845 -0
- sage/modular/quasimodform/ring.py +828 -0
- sage/modular/quatalg/all.py +3 -0
- sage/modular/quatalg/brandt.py +1642 -0
- sage/modular/ssmod/all.py +8 -0
- sage/modular/ssmod/ssmod.py +827 -0
- sage/rings/all__sagemath_schemes.py +1 -0
- sage/rings/polynomial/all__sagemath_schemes.py +1 -0
- sage/rings/polynomial/binary_form_reduce.py +585 -0
- sage/schemes/all.py +41 -0
- sage/schemes/berkovich/all.py +6 -0
- sage/schemes/berkovich/berkovich_cp_element.py +2582 -0
- sage/schemes/berkovich/berkovich_space.py +748 -0
- sage/schemes/curves/affine_curve.py +2928 -0
- sage/schemes/curves/all.py +33 -0
- sage/schemes/curves/closed_point.py +434 -0
- sage/schemes/curves/constructor.py +381 -0
- sage/schemes/curves/curve.py +542 -0
- sage/schemes/curves/plane_curve_arrangement.py +1283 -0
- sage/schemes/curves/point.py +463 -0
- sage/schemes/curves/projective_curve.py +3026 -0
- sage/schemes/curves/zariski_vankampen.py +1932 -0
- sage/schemes/cyclic_covers/all.py +2 -0
- sage/schemes/cyclic_covers/charpoly_frobenius.py +320 -0
- sage/schemes/cyclic_covers/constructor.py +137 -0
- sage/schemes/cyclic_covers/cycliccover_finite_field.py +1309 -0
- sage/schemes/cyclic_covers/cycliccover_generic.py +310 -0
- sage/schemes/elliptic_curves/BSD.py +1036 -0
- sage/schemes/elliptic_curves/Qcurves.py +592 -0
- sage/schemes/elliptic_curves/addition_formulas_ring.py +94 -0
- sage/schemes/elliptic_curves/all.py +49 -0
- sage/schemes/elliptic_curves/cardinality.py +609 -0
- sage/schemes/elliptic_curves/cm.py +1102 -0
- sage/schemes/elliptic_curves/constructor.py +1552 -0
- sage/schemes/elliptic_curves/ec_database.py +175 -0
- sage/schemes/elliptic_curves/ell_curve_isogeny.py +3972 -0
- sage/schemes/elliptic_curves/ell_egros.py +459 -0
- sage/schemes/elliptic_curves/ell_field.py +2836 -0
- sage/schemes/elliptic_curves/ell_finite_field.py +3359 -0
- sage/schemes/elliptic_curves/ell_generic.py +3760 -0
- sage/schemes/elliptic_curves/ell_local_data.py +1207 -0
- sage/schemes/elliptic_curves/ell_modular_symbols.py +775 -0
- sage/schemes/elliptic_curves/ell_number_field.py +4220 -0
- sage/schemes/elliptic_curves/ell_padic_field.py +107 -0
- sage/schemes/elliptic_curves/ell_point.py +4787 -0
- sage/schemes/elliptic_curves/ell_rational_field.py +7368 -0
- sage/schemes/elliptic_curves/ell_tate_curve.py +671 -0
- sage/schemes/elliptic_curves/ell_torsion.py +436 -0
- sage/schemes/elliptic_curves/ell_wp.py +352 -0
- sage/schemes/elliptic_curves/formal_group.py +760 -0
- sage/schemes/elliptic_curves/gal_reps.py +1459 -0
- sage/schemes/elliptic_curves/gal_reps_number_field.py +1669 -0
- sage/schemes/elliptic_curves/gp_simon.py +152 -0
- sage/schemes/elliptic_curves/heegner.py +7335 -0
- sage/schemes/elliptic_curves/height.py +2109 -0
- sage/schemes/elliptic_curves/hom.py +1406 -0
- sage/schemes/elliptic_curves/hom_composite.py +934 -0
- sage/schemes/elliptic_curves/hom_frobenius.py +522 -0
- sage/schemes/elliptic_curves/hom_scalar.py +531 -0
- sage/schemes/elliptic_curves/hom_sum.py +682 -0
- sage/schemes/elliptic_curves/hom_velusqrt.py +1290 -0
- sage/schemes/elliptic_curves/homset.py +271 -0
- sage/schemes/elliptic_curves/isogeny_class.py +1521 -0
- sage/schemes/elliptic_curves/isogeny_small_degree.py +2797 -0
- sage/schemes/elliptic_curves/jacobian.py +237 -0
- sage/schemes/elliptic_curves/kodaira_symbol.py +344 -0
- sage/schemes/elliptic_curves/kraus.py +1014 -0
- sage/schemes/elliptic_curves/lseries_ell.py +943 -0
- sage/schemes/elliptic_curves/mod5family.py +105 -0
- sage/schemes/elliptic_curves/mod_poly.py +197 -0
- sage/schemes/elliptic_curves/mod_sym_num.cpython-314t-darwin.so +0 -0
- sage/schemes/elliptic_curves/mod_sym_num.pyx +3796 -0
- sage/schemes/elliptic_curves/modular_parametrization.py +305 -0
- sage/schemes/elliptic_curves/padic_lseries.py +1793 -0
- sage/schemes/elliptic_curves/padics.py +1816 -0
- sage/schemes/elliptic_curves/period_lattice.py +2234 -0
- sage/schemes/elliptic_curves/period_lattice_region.cpython-314t-darwin.so +0 -0
- sage/schemes/elliptic_curves/period_lattice_region.pyx +722 -0
- sage/schemes/elliptic_curves/saturation.py +715 -0
- sage/schemes/elliptic_curves/sha_tate.py +1158 -0
- sage/schemes/elliptic_curves/weierstrass_morphism.py +1117 -0
- sage/schemes/elliptic_curves/weierstrass_transform.py +200 -0
- sage/schemes/hyperelliptic_curves/all.py +6 -0
- sage/schemes/hyperelliptic_curves/constructor.py +291 -0
- sage/schemes/hyperelliptic_curves/hyperelliptic_finite_field.py +1914 -0
- sage/schemes/hyperelliptic_curves/hyperelliptic_g2.py +192 -0
- sage/schemes/hyperelliptic_curves/hyperelliptic_generic.py +954 -0
- sage/schemes/hyperelliptic_curves/hyperelliptic_padic_field.py +1332 -0
- sage/schemes/hyperelliptic_curves/hyperelliptic_rational_field.py +84 -0
- sage/schemes/hyperelliptic_curves/invariants.py +410 -0
- sage/schemes/hyperelliptic_curves/jacobian_endomorphism_utils.py +315 -0
- sage/schemes/hyperelliptic_curves/jacobian_g2.py +32 -0
- sage/schemes/hyperelliptic_curves/jacobian_generic.py +419 -0
- sage/schemes/hyperelliptic_curves/jacobian_homset.py +186 -0
- sage/schemes/hyperelliptic_curves/jacobian_morphism.py +875 -0
- sage/schemes/hyperelliptic_curves/kummer_surface.py +99 -0
- sage/schemes/hyperelliptic_curves/mestre.py +302 -0
- sage/schemes/hyperelliptic_curves/monsky_washnitzer.py +3871 -0
- sage/schemes/jacobians/abstract_jacobian.py +277 -0
- sage/schemes/jacobians/all.py +2 -0
- sage/schemes/overview.py +161 -0
- sage/schemes/plane_conics/all.py +22 -0
- sage/schemes/plane_conics/con_field.py +1296 -0
- sage/schemes/plane_conics/con_finite_field.py +158 -0
- sage/schemes/plane_conics/con_number_field.py +456 -0
- sage/schemes/plane_conics/con_rational_field.py +406 -0
- sage/schemes/plane_conics/con_rational_function_field.py +580 -0
- sage/schemes/plane_conics/constructor.py +249 -0
- sage/schemes/plane_quartics/all.py +2 -0
- sage/schemes/plane_quartics/quartic_constructor.py +71 -0
- sage/schemes/plane_quartics/quartic_generic.py +73 -0
- sage/schemes/riemann_surfaces/all.py +1 -0
- sage/schemes/riemann_surfaces/riemann_surface.py +4117 -0
- sage_wheels/share/cremona/cremona_mini.db +0 -0
- sage_wheels/share/ellcurves/rank0 +30427 -0
- sage_wheels/share/ellcurves/rank1 +31871 -0
- sage_wheels/share/ellcurves/rank10 +6 -0
- sage_wheels/share/ellcurves/rank11 +6 -0
- sage_wheels/share/ellcurves/rank12 +1 -0
- sage_wheels/share/ellcurves/rank14 +1 -0
- sage_wheels/share/ellcurves/rank15 +1 -0
- sage_wheels/share/ellcurves/rank17 +1 -0
- sage_wheels/share/ellcurves/rank19 +1 -0
- sage_wheels/share/ellcurves/rank2 +2388 -0
- sage_wheels/share/ellcurves/rank20 +1 -0
- sage_wheels/share/ellcurves/rank21 +1 -0
- sage_wheels/share/ellcurves/rank22 +1 -0
- sage_wheels/share/ellcurves/rank23 +1 -0
- sage_wheels/share/ellcurves/rank24 +1 -0
- sage_wheels/share/ellcurves/rank28 +1 -0
- sage_wheels/share/ellcurves/rank3 +836 -0
- sage_wheels/share/ellcurves/rank4 +10 -0
- sage_wheels/share/ellcurves/rank5 +5 -0
- sage_wheels/share/ellcurves/rank6 +5 -0
- sage_wheels/share/ellcurves/rank7 +5 -0
- sage_wheels/share/ellcurves/rank8 +6 -0
- sage_wheels/share/ellcurves/rank9 +7 -0
|
@@ -0,0 +1,722 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-schemes
|
|
2
|
+
# sage.doctest: needs sage.rings.complex_double sage.symbolic
|
|
3
|
+
r"""
|
|
4
|
+
Regions in fundamental domains of period lattices
|
|
5
|
+
|
|
6
|
+
This module is used to represent sub-regions of a fundamental parallelogram
|
|
7
|
+
of the period lattice of an elliptic curve, used in computing minimum height
|
|
8
|
+
bounds.
|
|
9
|
+
|
|
10
|
+
In particular, these are the approximating sets ``S^{(v)}`` in section 3.2 of
|
|
11
|
+
Thotsaphon Thongjunthug's Ph.D. Thesis and paper [Tho2010]_.
|
|
12
|
+
|
|
13
|
+
AUTHORS:
|
|
14
|
+
|
|
15
|
+
- Robert Bradshaw (2010): initial version
|
|
16
|
+
|
|
17
|
+
- John Cremona (2014): added some docstrings and doctests
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
# ***************************************************************************
|
|
21
|
+
# Copyright (C) 2010 Robert Bradshaw <robertwb@math.washington.edu>
|
|
22
|
+
#
|
|
23
|
+
# This program is free software: you can redistribute it and/or modify
|
|
24
|
+
# it under the terms of the GNU General Public License as published by
|
|
25
|
+
# the Free Software Foundation, either version 2 of the License, or
|
|
26
|
+
# (at your option) any later version.
|
|
27
|
+
# https://www.gnu.org/licenses/
|
|
28
|
+
# ***************************************************************************
|
|
29
|
+
|
|
30
|
+
import numpy as np
|
|
31
|
+
cimport numpy as np
|
|
32
|
+
|
|
33
|
+
from sage.rings.cif import CIF
|
|
34
|
+
from cpython.object cimport Py_EQ, Py_NE
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
cdef class PeriodicRegion:
|
|
38
|
+
|
|
39
|
+
# The generators of the lattice, a complex numbers.
|
|
40
|
+
cdef public w1
|
|
41
|
+
cdef public w2
|
|
42
|
+
|
|
43
|
+
# A two-dimensional array of (essentially) booleans specifying the subset
|
|
44
|
+
# of parallelogram tiles that cover this region.
|
|
45
|
+
cdef readonly data
|
|
46
|
+
|
|
47
|
+
# Flag specifying whether bitmap represents the whole fundamental
|
|
48
|
+
# parallelogram, or only half (in which case it is symmetric about
|
|
49
|
+
# the center).
|
|
50
|
+
cdef readonly bint full
|
|
51
|
+
|
|
52
|
+
def __init__(self, w1, w2, data, full=True):
|
|
53
|
+
"""
|
|
54
|
+
EXAMPLES::
|
|
55
|
+
|
|
56
|
+
sage: import numpy as np
|
|
57
|
+
sage: from sage.schemes.elliptic_curves.period_lattice_region import PeriodicRegion
|
|
58
|
+
sage: S = PeriodicRegion(CDF(2), CDF(2*I), np.zeros((4, 4)))
|
|
59
|
+
sage: S.plot() # needs sage.plot
|
|
60
|
+
Graphics object consisting of 1 graphics primitive
|
|
61
|
+
sage: data = np.zeros((4, 4))
|
|
62
|
+
sage: data[1,1] = True
|
|
63
|
+
sage: S = PeriodicRegion(CDF(2), CDF(2*I+1), data)
|
|
64
|
+
sage: S.plot() # needs sage.plot
|
|
65
|
+
Graphics object consisting of 5 graphics primitives
|
|
66
|
+
"""
|
|
67
|
+
if data.dtype is not np.int8:
|
|
68
|
+
data = data.astype(np.int8)
|
|
69
|
+
self.w1 = w1
|
|
70
|
+
self.w2 = w2
|
|
71
|
+
self.data = data
|
|
72
|
+
self.full = full
|
|
73
|
+
|
|
74
|
+
def is_empty(self):
|
|
75
|
+
"""
|
|
76
|
+
Return whether this region is empty.
|
|
77
|
+
|
|
78
|
+
EXAMPLES::
|
|
79
|
+
|
|
80
|
+
sage: import numpy as np
|
|
81
|
+
sage: if int(np.version.short_version[0]) > 1:
|
|
82
|
+
....: _ = np.set_printoptions(legacy="1.25")
|
|
83
|
+
sage: from sage.schemes.elliptic_curves.period_lattice_region import PeriodicRegion
|
|
84
|
+
sage: data = np.zeros((4, 4))
|
|
85
|
+
sage: PeriodicRegion(CDF(2), CDF(2*I), data).is_empty()
|
|
86
|
+
True
|
|
87
|
+
sage: data[1,1] = True
|
|
88
|
+
sage: PeriodicRegion(CDF(2), CDF(2*I), data).is_empty()
|
|
89
|
+
False
|
|
90
|
+
"""
|
|
91
|
+
return self.data.sum() == 0
|
|
92
|
+
|
|
93
|
+
def _ensure_full(self):
|
|
94
|
+
"""
|
|
95
|
+
Ensure the bitmap in ``self.data`` represents the entire fundamental
|
|
96
|
+
parallelogram, expanding symmetry by duplicating data if necessary.
|
|
97
|
+
|
|
98
|
+
Mutates and returns ``self``.
|
|
99
|
+
|
|
100
|
+
EXAMPLES::
|
|
101
|
+
|
|
102
|
+
sage: import numpy as np
|
|
103
|
+
sage: from sage.schemes.elliptic_curves.period_lattice_region import PeriodicRegion
|
|
104
|
+
sage: data = np.zeros((4, 4))
|
|
105
|
+
sage: S = PeriodicRegion(CDF(2), CDF(2*I), data, full=False)
|
|
106
|
+
sage: S.data.shape
|
|
107
|
+
(4, 4)
|
|
108
|
+
sage: S.full
|
|
109
|
+
False
|
|
110
|
+
sage: _ = S._ensure_full()
|
|
111
|
+
sage: S.full
|
|
112
|
+
True
|
|
113
|
+
sage: S.data.shape
|
|
114
|
+
(4, 8)
|
|
115
|
+
sage: _ = S._ensure_full()
|
|
116
|
+
sage: S.data.shape
|
|
117
|
+
(4, 8)
|
|
118
|
+
"""
|
|
119
|
+
if not self.full:
|
|
120
|
+
rows, cols = self.data.shape
|
|
121
|
+
new_data = np.ndarray((rows, 2*cols), self.data.dtype)
|
|
122
|
+
new_data[:,0:cols] = self.data
|
|
123
|
+
new_data[::-1,-1:cols-1:-1] = self.data
|
|
124
|
+
self.data = new_data
|
|
125
|
+
self.full = True
|
|
126
|
+
return self
|
|
127
|
+
|
|
128
|
+
def ds(self):
|
|
129
|
+
"""
|
|
130
|
+
Return the sides of each parallelogram tile.
|
|
131
|
+
|
|
132
|
+
EXAMPLES::
|
|
133
|
+
|
|
134
|
+
sage: import numpy as np
|
|
135
|
+
sage: from sage.schemes.elliptic_curves.period_lattice_region import PeriodicRegion
|
|
136
|
+
sage: data = np.zeros((4, 4))
|
|
137
|
+
sage: S = PeriodicRegion(CDF(2), CDF(2*I), data, full=False)
|
|
138
|
+
sage: S.ds()
|
|
139
|
+
(0.5, 0.25*I)
|
|
140
|
+
sage: _ = S._ensure_full()
|
|
141
|
+
sage: S.ds()
|
|
142
|
+
(0.5, 0.25*I)
|
|
143
|
+
|
|
144
|
+
sage: data = np.zeros((8, 8))
|
|
145
|
+
sage: S = PeriodicRegion(CDF(1), CDF(I + 1/2), data)
|
|
146
|
+
sage: S.ds()
|
|
147
|
+
(0.125, 0.0625 + 0.125*I)
|
|
148
|
+
"""
|
|
149
|
+
m, n = self.data.shape
|
|
150
|
+
return self.w1/m, self.w2/(n * (2-self.full))
|
|
151
|
+
|
|
152
|
+
def verify(self, condition):
|
|
153
|
+
r"""
|
|
154
|
+
Given a condition that should hold for every line segment on
|
|
155
|
+
the boundary, verify that it actually does so.
|
|
156
|
+
|
|
157
|
+
INPUT:
|
|
158
|
+
|
|
159
|
+
- ``condition`` -- boolean-valued function on `\CC`
|
|
160
|
+
|
|
161
|
+
OUTPUT:
|
|
162
|
+
|
|
163
|
+
boolean according to whether the condition holds for all lines on the
|
|
164
|
+
boundary.
|
|
165
|
+
|
|
166
|
+
EXAMPLES::
|
|
167
|
+
|
|
168
|
+
sage: import numpy as np
|
|
169
|
+
sage: from sage.schemes.elliptic_curves.period_lattice_region import PeriodicRegion
|
|
170
|
+
sage: data = np.zeros((4, 4))
|
|
171
|
+
sage: data[1, 1] = True
|
|
172
|
+
sage: S = PeriodicRegion(CDF(1), CDF(I), data)
|
|
173
|
+
sage: S.border()
|
|
174
|
+
[(1, 1, 0), (2, 1, 0), (1, 1, 1), (1, 2, 1)]
|
|
175
|
+
sage: condition = lambda z: z.real().abs()<1/2
|
|
176
|
+
sage: S.verify(condition)
|
|
177
|
+
False
|
|
178
|
+
sage: condition = lambda z: z.real().abs()<1
|
|
179
|
+
sage: S.verify(condition)
|
|
180
|
+
True
|
|
181
|
+
"""
|
|
182
|
+
for line in self.border(False):
|
|
183
|
+
if not condition(line):
|
|
184
|
+
return False
|
|
185
|
+
return True
|
|
186
|
+
|
|
187
|
+
def refine(self, condition=None, int times=1):
|
|
188
|
+
r"""
|
|
189
|
+
Recursive function to refine the current tiling.
|
|
190
|
+
|
|
191
|
+
INPUT:
|
|
192
|
+
|
|
193
|
+
- ``condition`` -- function (default: ``None``); if not ``None``, only
|
|
194
|
+
keep tiles in the refinement which satisfy the condition
|
|
195
|
+
|
|
196
|
+
- ``times`` -- integer (default: 1); the number of times to refine.
|
|
197
|
+
Each refinement step halves the mesh size.
|
|
198
|
+
|
|
199
|
+
OUTPUT: the refined PeriodicRegion
|
|
200
|
+
|
|
201
|
+
EXAMPLES::
|
|
202
|
+
|
|
203
|
+
sage: import numpy as np
|
|
204
|
+
sage: from sage.schemes.elliptic_curves.period_lattice_region import PeriodicRegion
|
|
205
|
+
sage: data = np.zeros((4, 4))
|
|
206
|
+
sage: S = PeriodicRegion(CDF(2), CDF(2*I), data, full=False)
|
|
207
|
+
sage: S.ds()
|
|
208
|
+
(0.5, 0.25*I)
|
|
209
|
+
sage: S = S.refine()
|
|
210
|
+
sage: S.ds()
|
|
211
|
+
(0.25, 0.125*I)
|
|
212
|
+
sage: S = S.refine(2)
|
|
213
|
+
sage: S.ds()
|
|
214
|
+
(0.125, 0.0625*I)
|
|
215
|
+
"""
|
|
216
|
+
if times <= 0:
|
|
217
|
+
return self
|
|
218
|
+
cdef int i, j, m, n
|
|
219
|
+
cdef np.ndarray[np.npy_int8, ndim=2] less, fuzz, new_data
|
|
220
|
+
m, n = self.data.shape
|
|
221
|
+
if condition is None:
|
|
222
|
+
new_data = np.ndarray((2*m, 2*n), self.data.dtype)
|
|
223
|
+
new_data[0::2,0::2] = self.data
|
|
224
|
+
new_data[1::2,0::2] = self.data
|
|
225
|
+
new_data[0::2,1::2] = self.data
|
|
226
|
+
new_data[1::2,1::2] = self.data
|
|
227
|
+
else:
|
|
228
|
+
more = self.expand().data
|
|
229
|
+
less = self.contract().data
|
|
230
|
+
fuzz = less ^ more
|
|
231
|
+
new_data = np.zeros((2*m, 2*n), self.data.dtype)
|
|
232
|
+
dw1, dw2 = self.ds()
|
|
233
|
+
dw1 /= 2
|
|
234
|
+
dw2 /= 2
|
|
235
|
+
for i in range(2*m):
|
|
236
|
+
for j in range(2*n):
|
|
237
|
+
if less[i//2, j//2]:
|
|
238
|
+
new_data[i,j] = True
|
|
239
|
+
elif fuzz[i//2, j//2]:
|
|
240
|
+
new_data[i,j] = condition(dw1*(i+.5) + dw2*(j+.5))
|
|
241
|
+
return PeriodicRegion(self.w1, self.w2, new_data, self.full).refine(condition, times-1)
|
|
242
|
+
|
|
243
|
+
def expand(self, bint corners=True):
|
|
244
|
+
"""
|
|
245
|
+
Return a region containing this region by adding all neighbors of
|
|
246
|
+
internal tiles.
|
|
247
|
+
|
|
248
|
+
EXAMPLES::
|
|
249
|
+
|
|
250
|
+
sage: import numpy as np
|
|
251
|
+
sage: from sage.schemes.elliptic_curves.period_lattice_region import PeriodicRegion
|
|
252
|
+
sage: data = np.zeros((4, 4))
|
|
253
|
+
sage: data[1,1] = True
|
|
254
|
+
sage: S = PeriodicRegion(CDF(1), CDF(I + 1/2), data)
|
|
255
|
+
sage: S.plot() # needs sage.plot
|
|
256
|
+
Graphics object consisting of 5 graphics primitives
|
|
257
|
+
sage: S.expand().plot() # needs sage.plot
|
|
258
|
+
Graphics object consisting of 13 graphics primitives
|
|
259
|
+
sage: S.expand().data
|
|
260
|
+
array([[1, 1, 1, 0],
|
|
261
|
+
[1, 1, 1, 0],
|
|
262
|
+
[1, 1, 1, 0],
|
|
263
|
+
[0, 0, 0, 0]], dtype=int8)
|
|
264
|
+
sage: S.expand(corners=False).plot() # needs sage.plot
|
|
265
|
+
Graphics object consisting of 13 graphics primitives
|
|
266
|
+
sage: S.expand(corners=False).data
|
|
267
|
+
array([[0, 1, 0, 0],
|
|
268
|
+
[1, 1, 1, 0],
|
|
269
|
+
[0, 1, 0, 0],
|
|
270
|
+
[0, 0, 0, 0]], dtype=int8)
|
|
271
|
+
"""
|
|
272
|
+
cdef int i, j, m, n
|
|
273
|
+
m, n = self.data.shape
|
|
274
|
+
cdef np.ndarray[np.npy_int8, ndim=2] framed, new_data
|
|
275
|
+
framed = frame_data(self.data, self.full)
|
|
276
|
+
new_data = np.zeros((m+2, n+2), self.data.dtype)
|
|
277
|
+
for i in range(m):
|
|
278
|
+
for j in range(n):
|
|
279
|
+
if framed[i, j]:
|
|
280
|
+
new_data[i, j] = True
|
|
281
|
+
new_data[i - 1, j] = True
|
|
282
|
+
new_data[i + 1, j] = True
|
|
283
|
+
new_data[i, j - 1] = True
|
|
284
|
+
new_data[i, j + 1] = True
|
|
285
|
+
if corners:
|
|
286
|
+
new_data[i - 1, j - 1] = True
|
|
287
|
+
new_data[i + 1, j - 1] = True
|
|
288
|
+
new_data[i + 1, j + 1] = True
|
|
289
|
+
new_data[i - 1, j + 1] = True
|
|
290
|
+
return PeriodicRegion(self.w1, self.w2, unframe_data(new_data, self.full), self.full)
|
|
291
|
+
|
|
292
|
+
def contract(self, corners=True):
|
|
293
|
+
"""
|
|
294
|
+
Opposite (but not inverse) of expand; removes neighbors of complement.
|
|
295
|
+
|
|
296
|
+
EXAMPLES::
|
|
297
|
+
|
|
298
|
+
sage: import numpy as np
|
|
299
|
+
sage: if int(np.version.short_version[0]) > 1:
|
|
300
|
+
....: _ = np.set_printoptions(legacy="1.25")
|
|
301
|
+
sage: from sage.schemes.elliptic_curves.period_lattice_region import PeriodicRegion
|
|
302
|
+
sage: data = np.zeros((10, 10))
|
|
303
|
+
sage: data[1:4,1:4] = True
|
|
304
|
+
sage: S = PeriodicRegion(CDF(1), CDF(I + 1/2), data)
|
|
305
|
+
sage: S.plot() # needs sage.plot
|
|
306
|
+
Graphics object consisting of 13 graphics primitives
|
|
307
|
+
sage: S.contract().plot() # needs sage.plot
|
|
308
|
+
Graphics object consisting of 5 graphics primitives
|
|
309
|
+
sage: S.contract().data.sum()
|
|
310
|
+
1
|
|
311
|
+
sage: S.contract().contract().is_empty()
|
|
312
|
+
True
|
|
313
|
+
"""
|
|
314
|
+
return ~(~self).expand(corners)
|
|
315
|
+
|
|
316
|
+
def __contains__(self, z):
|
|
317
|
+
"""
|
|
318
|
+
Return whether this region contains the given point.
|
|
319
|
+
|
|
320
|
+
EXAMPLES::
|
|
321
|
+
|
|
322
|
+
sage: import numpy as np
|
|
323
|
+
sage: if int(np.version.short_version[0]) > 1:
|
|
324
|
+
....: _ = np.set_printoptions(legacy="1.25")
|
|
325
|
+
sage: from sage.schemes.elliptic_curves.period_lattice_region import PeriodicRegion
|
|
326
|
+
sage: data = np.zeros((4, 4))
|
|
327
|
+
sage: data[1,1] = True
|
|
328
|
+
sage: S = PeriodicRegion(CDF(2), CDF(2*I), data, full=False)
|
|
329
|
+
sage: CDF(0, 0) in S
|
|
330
|
+
False
|
|
331
|
+
sage: CDF(0.6, 0.6) in S
|
|
332
|
+
True
|
|
333
|
+
sage: CDF(1.6, 0.6) in S
|
|
334
|
+
False
|
|
335
|
+
sage: CDF(6.6, 4.6) in S
|
|
336
|
+
True
|
|
337
|
+
sage: CDF(6.6, -1.4) in S
|
|
338
|
+
True
|
|
339
|
+
|
|
340
|
+
sage: w1 = CDF(1.4)
|
|
341
|
+
sage: w2 = CDF(1.2 * I - .3)
|
|
342
|
+
sage: S = PeriodicRegion(w1, w2, data)
|
|
343
|
+
sage: z = w1/2 + w2/2; z in S
|
|
344
|
+
False
|
|
345
|
+
sage: z = w1/3 + w2/3; z in S
|
|
346
|
+
True
|
|
347
|
+
sage: z = w1/3 + w2/3 + 5*w1 - 6*w2; z in S
|
|
348
|
+
True
|
|
349
|
+
"""
|
|
350
|
+
CC = self.w1.parent()
|
|
351
|
+
RR = CC.construction()[1]
|
|
352
|
+
basis_matrix = (RR**(2,2))((tuple(self.w1), tuple(self.w2))).transpose()
|
|
353
|
+
i, j = basis_matrix.solve_right((RR**2)(tuple(CC(z))))
|
|
354
|
+
# Get the fractional part.
|
|
355
|
+
i -= int(i)
|
|
356
|
+
j -= int(j)
|
|
357
|
+
if i < 0:
|
|
358
|
+
i += 1
|
|
359
|
+
if j < 0:
|
|
360
|
+
j += 1
|
|
361
|
+
if not self.full and j > 0.5:
|
|
362
|
+
j = 1 - j
|
|
363
|
+
i = 1 - i
|
|
364
|
+
m, n = self.data.shape
|
|
365
|
+
return self.data[int(m * i), int(n * j)]
|
|
366
|
+
|
|
367
|
+
def __truediv__(self, unsigned int n):
|
|
368
|
+
"""
|
|
369
|
+
Return a new region of the same resolution that is the image
|
|
370
|
+
of this region under the map z -> z/n.
|
|
371
|
+
|
|
372
|
+
The resolution is the same, so some detail may be lost. The result is
|
|
373
|
+
always at worse a superset of the true image.
|
|
374
|
+
|
|
375
|
+
EXAMPLES::
|
|
376
|
+
|
|
377
|
+
sage: import numpy as np
|
|
378
|
+
sage: if int(np.version.short_version[0]) > 1:
|
|
379
|
+
....: _ = np.set_printoptions(legacy="1.25")
|
|
380
|
+
sage: from sage.schemes.elliptic_curves.period_lattice_region import PeriodicRegion
|
|
381
|
+
|
|
382
|
+
sage: data = np.zeros((20, 20))
|
|
383
|
+
sage: data[2, 2:12] = True
|
|
384
|
+
sage: data[2:6, 2] = True
|
|
385
|
+
sage: data[3, 3] = True
|
|
386
|
+
sage: S = PeriodicRegion(CDF(1), CDF(I + 1/2), data)
|
|
387
|
+
sage: S.plot() # needs sage.plot
|
|
388
|
+
Graphics object consisting of 29 graphics primitives
|
|
389
|
+
sage: (S / 2).plot() # needs sage.plot
|
|
390
|
+
Graphics object consisting of 57 graphics primitives
|
|
391
|
+
sage: (S / 3).plot() # needs sage.plot
|
|
392
|
+
Graphics object consisting of 109 graphics primitives
|
|
393
|
+
sage: (S / 2 / 3) == (S / 6) == (S / 3 / 2)
|
|
394
|
+
True
|
|
395
|
+
|
|
396
|
+
sage: data = np.zeros((100, 100))
|
|
397
|
+
sage: data[2, 3] = True
|
|
398
|
+
sage: data[7, 9] = True
|
|
399
|
+
sage: S = PeriodicRegion(CDF(1), CDF(I), data)
|
|
400
|
+
sage: inside = [.025 + .035j, .075 + .095j]
|
|
401
|
+
sage: all(z in S for z in inside)
|
|
402
|
+
True
|
|
403
|
+
sage: all(z/2 + j/2 + k/2 in S/2 for z in inside for j in range(2) for k in range(2))
|
|
404
|
+
True
|
|
405
|
+
sage: all(z/3 + j/3 + k/3 in S/3 for z in inside for j in range(3) for k in range(3))
|
|
406
|
+
True
|
|
407
|
+
sage: outside = [.025 + .095j, .075 + .035j]
|
|
408
|
+
sage: any(z in S for z in outside)
|
|
409
|
+
False
|
|
410
|
+
sage: any(z/2 + j/2 + k/2 in S/2 for z in outside for j in range(2) for k in range(2))
|
|
411
|
+
False
|
|
412
|
+
sage: any(z/3 + j/3 + k/3 in S/3 for z in outside for j in range(3) for k in range(3))
|
|
413
|
+
False
|
|
414
|
+
|
|
415
|
+
sage: (S / 1) is S
|
|
416
|
+
True
|
|
417
|
+
sage: S / 0
|
|
418
|
+
Traceback (most recent call last):
|
|
419
|
+
...
|
|
420
|
+
ValueError: divisor must be positive
|
|
421
|
+
sage: S / (-1)
|
|
422
|
+
Traceback (most recent call last):
|
|
423
|
+
...
|
|
424
|
+
OverflowError: can...t convert negative value to unsigned int
|
|
425
|
+
"""
|
|
426
|
+
cdef unsigned int i, j, a, b, rows, cols
|
|
427
|
+
if n <= 1:
|
|
428
|
+
if n == 1:
|
|
429
|
+
return self
|
|
430
|
+
raise ValueError("divisor must be positive")
|
|
431
|
+
self._ensure_full()
|
|
432
|
+
cdef np.ndarray[np.npy_int8, ndim=2] data, new_data
|
|
433
|
+
data = self.data
|
|
434
|
+
rows, cols = self.data.shape
|
|
435
|
+
|
|
436
|
+
new_data = np.zeros(self.data.shape, self.data.dtype)
|
|
437
|
+
for i in range(rows):
|
|
438
|
+
for j in range(cols):
|
|
439
|
+
if data[i,j]:
|
|
440
|
+
for a in range(n):
|
|
441
|
+
for b in range(n):
|
|
442
|
+
new_data[(a*rows+i)//n, (b*cols+j)//n] = data[i,j]
|
|
443
|
+
return PeriodicRegion(self.w1, self.w2, new_data)
|
|
444
|
+
|
|
445
|
+
def __invert__(self):
|
|
446
|
+
"""
|
|
447
|
+
Return the complement of this region.
|
|
448
|
+
|
|
449
|
+
EXAMPLES::
|
|
450
|
+
|
|
451
|
+
sage: import numpy as np
|
|
452
|
+
sage: from sage.schemes.elliptic_curves.period_lattice_region import PeriodicRegion
|
|
453
|
+
sage: data = np.zeros((4, 4))
|
|
454
|
+
sage: data[1,1] = True
|
|
455
|
+
sage: S = PeriodicRegion(CDF(1), CDF(I), data)
|
|
456
|
+
sage: .3 + .3j in S
|
|
457
|
+
True
|
|
458
|
+
sage: .3 + .3j in ~S
|
|
459
|
+
False
|
|
460
|
+
sage: 0 in S
|
|
461
|
+
False
|
|
462
|
+
sage: 0 in ~S
|
|
463
|
+
True
|
|
464
|
+
"""
|
|
465
|
+
return PeriodicRegion(self.w1, self.w2, 1-self.data, self.full)
|
|
466
|
+
|
|
467
|
+
def __and__(left, right):
|
|
468
|
+
"""
|
|
469
|
+
Return the intersection of ``left`` and ``right``.
|
|
470
|
+
|
|
471
|
+
EXAMPLES::
|
|
472
|
+
|
|
473
|
+
sage: import numpy as np
|
|
474
|
+
sage: from sage.schemes.elliptic_curves.period_lattice_region import PeriodicRegion
|
|
475
|
+
sage: data = np.zeros((4, 4))
|
|
476
|
+
sage: data[1, 1:3] = True
|
|
477
|
+
sage: S1 = PeriodicRegion(CDF(1), CDF(I), data)
|
|
478
|
+
sage: data = np.zeros((4, 4))
|
|
479
|
+
sage: data[1:3, 1] = True
|
|
480
|
+
sage: S2 = PeriodicRegion(CDF(1), CDF(I), data)
|
|
481
|
+
sage: (S1 & S2).data
|
|
482
|
+
array([[0, 0, 0, 0],
|
|
483
|
+
[0, 1, 0, 0],
|
|
484
|
+
[0, 0, 0, 0],
|
|
485
|
+
[0, 0, 0, 0]], dtype=int8)
|
|
486
|
+
"""
|
|
487
|
+
assert isinstance(left, PeriodicRegion) and isinstance(right, PeriodicRegion)
|
|
488
|
+
assert left.w1 == right.w1 and left.w2 == right.w2
|
|
489
|
+
if left.full ^ right.full:
|
|
490
|
+
left._ensure_full()
|
|
491
|
+
right._ensure_full()
|
|
492
|
+
return PeriodicRegion(left.w1, left.w2, left.data & right.data, left.full)
|
|
493
|
+
|
|
494
|
+
def __xor__(left, right):
|
|
495
|
+
"""
|
|
496
|
+
Return the union of ``left`` and ``right`` minus the intersection of
|
|
497
|
+
``left`` and ``right``.
|
|
498
|
+
|
|
499
|
+
EXAMPLES::
|
|
500
|
+
|
|
501
|
+
sage: import numpy as np
|
|
502
|
+
sage: from sage.schemes.elliptic_curves.period_lattice_region import PeriodicRegion
|
|
503
|
+
sage: data = np.zeros((4, 4))
|
|
504
|
+
sage: data[1, 1:3] = True
|
|
505
|
+
sage: S1 = PeriodicRegion(CDF(1), CDF(I), data)
|
|
506
|
+
sage: data = np.zeros((4, 4))
|
|
507
|
+
sage: data[1:3, 1] = True
|
|
508
|
+
sage: S2 = PeriodicRegion(CDF(1), CDF(I), data)
|
|
509
|
+
sage: (S1 ^^ S2).data
|
|
510
|
+
array([[0, 0, 0, 0],
|
|
511
|
+
[0, 0, 1, 0],
|
|
512
|
+
[0, 1, 0, 0],
|
|
513
|
+
[0, 0, 0, 0]], dtype=int8)
|
|
514
|
+
"""
|
|
515
|
+
assert isinstance(left, PeriodicRegion) and isinstance(right, PeriodicRegion)
|
|
516
|
+
assert left.w1 == right.w1 and left.w2 == right.w2
|
|
517
|
+
if left.full ^ right.full:
|
|
518
|
+
left._ensure_full()
|
|
519
|
+
right._ensure_full()
|
|
520
|
+
return PeriodicRegion(left.w1, left.w2, left.data ^ right.data, left.full)
|
|
521
|
+
|
|
522
|
+
def __richcmp__(left, right, op):
|
|
523
|
+
"""
|
|
524
|
+
Compare two regions.
|
|
525
|
+
|
|
526
|
+
.. NOTE:: This is good for equality but not an ordering relation.
|
|
527
|
+
|
|
528
|
+
TESTS::
|
|
529
|
+
|
|
530
|
+
sage: import numpy as np
|
|
531
|
+
sage: if int(np.version.short_version[0]) > 1:
|
|
532
|
+
....: _ = np.set_printoptions(legacy="1.25")
|
|
533
|
+
sage: from sage.schemes.elliptic_curves.period_lattice_region import PeriodicRegion
|
|
534
|
+
sage: data = np.zeros((4, 4))
|
|
535
|
+
sage: data[1, 1] = True
|
|
536
|
+
sage: S1 = PeriodicRegion(CDF(1), CDF(I), data)
|
|
537
|
+
sage: data = np.zeros((4, 4))
|
|
538
|
+
sage: data[1, 1] = True
|
|
539
|
+
sage: S2 = PeriodicRegion(CDF(1), CDF(I), data)
|
|
540
|
+
sage: data = np.zeros((4, 4))
|
|
541
|
+
sage: data[2, 2] = True
|
|
542
|
+
sage: S3 = PeriodicRegion(CDF(1), CDF(I), data)
|
|
543
|
+
sage: S1 == S2
|
|
544
|
+
True
|
|
545
|
+
sage: S2 == S3
|
|
546
|
+
False
|
|
547
|
+
"""
|
|
548
|
+
if type(left) is not type(right) or op not in [Py_EQ, Py_NE]:
|
|
549
|
+
return NotImplemented
|
|
550
|
+
|
|
551
|
+
if (left.w1, left.w2) != (right.w1, right.w2):
|
|
552
|
+
equal = False
|
|
553
|
+
else:
|
|
554
|
+
if left.full ^ right.full:
|
|
555
|
+
left._ensure_full()
|
|
556
|
+
right._ensure_full()
|
|
557
|
+
equal = (left.data == right.data).all()
|
|
558
|
+
|
|
559
|
+
if op is Py_EQ:
|
|
560
|
+
return equal
|
|
561
|
+
return not equal
|
|
562
|
+
|
|
563
|
+
def border(self, raw=True):
|
|
564
|
+
"""
|
|
565
|
+
Return the boundary of this region as set of tile boundaries.
|
|
566
|
+
|
|
567
|
+
If raw is true, returns a list with respect to the internal bitmap,
|
|
568
|
+
otherwise returns complex intervals covering the border.
|
|
569
|
+
|
|
570
|
+
EXAMPLES::
|
|
571
|
+
|
|
572
|
+
sage: import numpy as np
|
|
573
|
+
sage: from sage.schemes.elliptic_curves.period_lattice_region import PeriodicRegion
|
|
574
|
+
sage: data = np.zeros((4, 4))
|
|
575
|
+
sage: data[1, 1] = True
|
|
576
|
+
sage: PeriodicRegion(CDF(1), CDF(I), data).border()
|
|
577
|
+
[(1, 1, 0), (2, 1, 0), (1, 1, 1), (1, 2, 1)]
|
|
578
|
+
sage: PeriodicRegion(CDF(2), CDF(I-1/2), data).border()
|
|
579
|
+
[(1, 1, 0), (2, 1, 0), (1, 1, 1), (1, 2, 1)]
|
|
580
|
+
|
|
581
|
+
sage: PeriodicRegion(CDF(1), CDF(I), data).border(raw=False)
|
|
582
|
+
[0.25000000000000000? + 1.?*I,
|
|
583
|
+
0.50000000000000000? + 1.?*I,
|
|
584
|
+
1.? + 0.25000000000000000?*I,
|
|
585
|
+
1.? + 0.50000000000000000?*I]
|
|
586
|
+
sage: PeriodicRegion(CDF(2), CDF(I-1/2), data).border(raw=False)
|
|
587
|
+
[0.3? + 1.?*I,
|
|
588
|
+
0.8? + 1.?*I,
|
|
589
|
+
1.? + 0.25000000000000000?*I,
|
|
590
|
+
1.? + 0.50000000000000000?*I]
|
|
591
|
+
|
|
592
|
+
sage: data[1:3, 2] = True
|
|
593
|
+
sage: PeriodicRegion(CDF(1), CDF(I), data).border()
|
|
594
|
+
[(1, 1, 0), (2, 1, 0), (1, 1, 1), (1, 2, 0), (1, 3, 1), (3, 2, 0), (2, 2, 1), (2, 3, 1)]
|
|
595
|
+
"""
|
|
596
|
+
cdef np.ndarray[np.npy_int8, ndim=2] framed = frame_data(self.data, self.full)
|
|
597
|
+
cdef int m, n
|
|
598
|
+
m, n = self.data.shape
|
|
599
|
+
cdef int i, j
|
|
600
|
+
L = []
|
|
601
|
+
for i in range(m):
|
|
602
|
+
for j in range(n):
|
|
603
|
+
if framed[i,j]:
|
|
604
|
+
if not framed[i-1, j]:
|
|
605
|
+
L.append((i, j, 0))
|
|
606
|
+
if not framed[i+1, j]:
|
|
607
|
+
L.append((i+1, j, 0))
|
|
608
|
+
if not framed[i, j-1]:
|
|
609
|
+
L.append((i, j, 1))
|
|
610
|
+
if not framed[i, j+1]:
|
|
611
|
+
L.append((i, j+1, 1))
|
|
612
|
+
if not raw:
|
|
613
|
+
dw1, dw2 = self.ds()
|
|
614
|
+
for ix, (i, j, dir) in enumerate(L):
|
|
615
|
+
L[ix] = CIF(i*dw1 + j*dw2).union(CIF((i+dir)*dw1 + (j+(1-dir))*dw2))
|
|
616
|
+
return L
|
|
617
|
+
|
|
618
|
+
def innermost_point(self):
|
|
619
|
+
"""
|
|
620
|
+
Return a point well inside the region, specifically the center of
|
|
621
|
+
(one of) the last tile(s) to be removed on contraction.
|
|
622
|
+
|
|
623
|
+
EXAMPLES::
|
|
624
|
+
|
|
625
|
+
sage: import numpy as np
|
|
626
|
+
sage: from sage.schemes.elliptic_curves.period_lattice_region import PeriodicRegion
|
|
627
|
+
sage: data = np.zeros((10, 10))
|
|
628
|
+
sage: data[1:4, 1:4] = True
|
|
629
|
+
sage: data[1, 0:8] = True
|
|
630
|
+
sage: S = PeriodicRegion(CDF(1), CDF(I+1/2), data)
|
|
631
|
+
sage: S.innermost_point()
|
|
632
|
+
0.375 + 0.25*I
|
|
633
|
+
sage: S.plot() + point(S.innermost_point()) # needs sage.plot
|
|
634
|
+
Graphics object consisting of 24 graphics primitives
|
|
635
|
+
"""
|
|
636
|
+
if self.is_empty():
|
|
637
|
+
from sage.categories.sets_cat import EmptySetError
|
|
638
|
+
raise EmptySetError("region is empty")
|
|
639
|
+
inside = self
|
|
640
|
+
while not inside.is_empty():
|
|
641
|
+
self, inside = inside, inside.contract(corners=False)
|
|
642
|
+
i, j = tuple(np.transpose(self.data.nonzero())[0])
|
|
643
|
+
dw1, dw2 = self.ds()
|
|
644
|
+
return float(i + 0.5) * dw1 + float(j + 0.5) * dw2
|
|
645
|
+
|
|
646
|
+
def plot(self, **kwds):
|
|
647
|
+
"""
|
|
648
|
+
Plot this region in the fundamental lattice. If ``full`` is ``False``, plots
|
|
649
|
+
only the lower half. Note that the true nature of this region is periodic.
|
|
650
|
+
|
|
651
|
+
EXAMPLES::
|
|
652
|
+
|
|
653
|
+
sage: import numpy as np
|
|
654
|
+
sage: from sage.schemes.elliptic_curves.period_lattice_region import PeriodicRegion
|
|
655
|
+
sage: data = np.zeros((10, 10))
|
|
656
|
+
sage: data[2, 2:8] = True
|
|
657
|
+
sage: data[2:5, 2] = True
|
|
658
|
+
sage: data[3, 3] = True
|
|
659
|
+
sage: S = PeriodicRegion(CDF(1), CDF(I + 1/2), data)
|
|
660
|
+
sage: plot(S) + plot(S.expand(), rgbcolor=(1, 0, 1), thickness=2) # needs sage.plot
|
|
661
|
+
Graphics object consisting of 46 graphics primitives
|
|
662
|
+
"""
|
|
663
|
+
from sage.plot.line import line
|
|
664
|
+
dw1, dw2 = self.ds()
|
|
665
|
+
L = []
|
|
666
|
+
F = line([(0,0), tuple(self.w1),
|
|
667
|
+
tuple(self.w1+self.w2), tuple(self.w2), (0,0)])
|
|
668
|
+
if not self.full:
|
|
669
|
+
F += line([tuple(self.w2/2), tuple(self.w1+self.w2/2)])
|
|
670
|
+
if 'rgbcolor' not in kwds:
|
|
671
|
+
kwds['rgbcolor'] = 'red'
|
|
672
|
+
for i, j, dir in self.border():
|
|
673
|
+
ii, jj = i+dir, j+(1-dir)
|
|
674
|
+
L.append(line([tuple(i*dw1 + j*dw2), tuple(ii*dw1 + jj*dw2)], **kwds))
|
|
675
|
+
return sum(L, F)
|
|
676
|
+
|
|
677
|
+
|
|
678
|
+
cdef frame_data(data, bint full=True):
|
|
679
|
+
"""
|
|
680
|
+
Helper function for PeriodicRegion.expand() and
|
|
681
|
+
PeriodicRegion.border(). This makes "wrapping around" work
|
|
682
|
+
transparently for symmetric regions (full=False) as well.
|
|
683
|
+
|
|
684
|
+
Idea:
|
|
685
|
+
|
|
686
|
+
[[a, b, c] [[a, b, c, a, c],
|
|
687
|
+
[d, e, f] --> [d, e, f, d, f],
|
|
688
|
+
[g, h, i]] [g, h, i, g, i],
|
|
689
|
+
[a, b, c, a, c],
|
|
690
|
+
[g, h, i, g, i]]
|
|
691
|
+
"""
|
|
692
|
+
m, n = data.shape
|
|
693
|
+
framed = np.empty((m+2, n+2), data.dtype)
|
|
694
|
+
# center
|
|
695
|
+
framed[:-2,:-2] = data
|
|
696
|
+
# top and bottom
|
|
697
|
+
if full:
|
|
698
|
+
framed[:-2,-1] = data[:,-1]
|
|
699
|
+
framed[:-2,-2] = data[:, 0]
|
|
700
|
+
else:
|
|
701
|
+
framed[:-2,-1] = data[::-1, 0]
|
|
702
|
+
framed[:-2,-2] = data[::-1,-1]
|
|
703
|
+
# left and right
|
|
704
|
+
framed[-2,:] = framed[0,:]
|
|
705
|
+
framed[-1,:] = framed[-3,:]
|
|
706
|
+
return framed
|
|
707
|
+
|
|
708
|
+
cdef unframe_data(framed, bint full=True):
|
|
709
|
+
"""
|
|
710
|
+
Helper function for PeriodicRegion.expand(). This glues the
|
|
711
|
+
borders together using the "or" operator.
|
|
712
|
+
"""
|
|
713
|
+
framed = framed.copy()
|
|
714
|
+
framed[0,:] |= framed[-2,:]
|
|
715
|
+
framed[-3,:] |= framed[-1,:]
|
|
716
|
+
if full:
|
|
717
|
+
framed[:-2,-3] |= framed[:-2,-1]
|
|
718
|
+
framed[:-2, 0] |= framed[:-2,-2]
|
|
719
|
+
else:
|
|
720
|
+
framed[-3::-1, 0] |= framed[:-2,-1]
|
|
721
|
+
framed[-3::-1,-3] |= framed[:-2,-2]
|
|
722
|
+
return framed[:-2,:-2]
|