passagemath-modules 10.6.31__cp314-cp314-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-modules might be problematic. Click here for more details.
- passagemath_modules-10.6.31.dist-info/METADATA +281 -0
- passagemath_modules-10.6.31.dist-info/RECORD +808 -0
- passagemath_modules-10.6.31.dist-info/WHEEL +5 -0
- passagemath_modules-10.6.31.dist-info/top_level.txt +2 -0
- passagemath_modules.libs/libgcc_s-0cd532bd.so.1 +0 -0
- passagemath_modules.libs/libgfortran-2c33b284.so.5.0.0 +0 -0
- passagemath_modules.libs/libgmp-0e7fc84e.so.10.5.0 +0 -0
- passagemath_modules.libs/libgsl-42cda06f.so.28.0.0 +0 -0
- passagemath_modules.libs/libmpc-d8ebe4b5.so.3.3.1 +0 -0
- passagemath_modules.libs/libmpfr-aaecbfc0.so.6.2.1 +0 -0
- passagemath_modules.libs/libopenblasp-r0-905cb27d.3.29.so +0 -0
- passagemath_modules.libs/libquadmath-bb76a5fc.so.0.0.0 +0 -0
- sage/algebras/all__sagemath_modules.py +20 -0
- sage/algebras/catalog.py +148 -0
- sage/algebras/clifford_algebra.py +3107 -0
- sage/algebras/clifford_algebra_element.cpython-314-x86_64-linux-musl.so +0 -0
- sage/algebras/clifford_algebra_element.pxd +16 -0
- sage/algebras/clifford_algebra_element.pyx +997 -0
- sage/algebras/commutative_dga.py +4252 -0
- sage/algebras/exterior_algebra_groebner.cpython-314-x86_64-linux-musl.so +0 -0
- sage/algebras/exterior_algebra_groebner.pxd +55 -0
- sage/algebras/exterior_algebra_groebner.pyx +727 -0
- sage/algebras/finite_dimensional_algebras/all.py +2 -0
- sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra.py +1029 -0
- sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_element.cpython-314-x86_64-linux-musl.so +0 -0
- sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_element.pxd +12 -0
- sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_element.pyx +706 -0
- sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_ideal.py +196 -0
- sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_morphism.py +255 -0
- sage/algebras/finite_gca.py +528 -0
- sage/algebras/group_algebra.py +232 -0
- sage/algebras/lie_algebras/abelian.py +197 -0
- sage/algebras/lie_algebras/affine_lie_algebra.py +1213 -0
- sage/algebras/lie_algebras/all.py +25 -0
- sage/algebras/lie_algebras/all__sagemath_modules.py +1 -0
- sage/algebras/lie_algebras/bch.py +177 -0
- sage/algebras/lie_algebras/bgg_dual_module.py +1184 -0
- sage/algebras/lie_algebras/bgg_resolution.py +232 -0
- sage/algebras/lie_algebras/center_uea.py +767 -0
- sage/algebras/lie_algebras/classical_lie_algebra.py +2516 -0
- sage/algebras/lie_algebras/examples.py +683 -0
- sage/algebras/lie_algebras/free_lie_algebra.py +973 -0
- sage/algebras/lie_algebras/heisenberg.py +820 -0
- sage/algebras/lie_algebras/lie_algebra.py +1562 -0
- sage/algebras/lie_algebras/lie_algebra_element.cpython-314-x86_64-linux-musl.so +0 -0
- sage/algebras/lie_algebras/lie_algebra_element.pxd +68 -0
- sage/algebras/lie_algebras/lie_algebra_element.pyx +2122 -0
- sage/algebras/lie_algebras/morphism.py +661 -0
- sage/algebras/lie_algebras/nilpotent_lie_algebra.py +457 -0
- sage/algebras/lie_algebras/onsager.py +1324 -0
- sage/algebras/lie_algebras/poincare_birkhoff_witt.py +816 -0
- sage/algebras/lie_algebras/quotient.py +462 -0
- sage/algebras/lie_algebras/rank_two_heisenberg_virasoro.py +355 -0
- sage/algebras/lie_algebras/representation.py +1040 -0
- sage/algebras/lie_algebras/structure_coefficients.py +459 -0
- sage/algebras/lie_algebras/subalgebra.py +967 -0
- sage/algebras/lie_algebras/symplectic_derivation.py +289 -0
- sage/algebras/lie_algebras/verma_module.py +1630 -0
- sage/algebras/lie_algebras/virasoro.py +1186 -0
- sage/algebras/octonion_algebra.cpython-314-x86_64-linux-musl.so +0 -0
- sage/algebras/octonion_algebra.pxd +20 -0
- sage/algebras/octonion_algebra.pyx +987 -0
- sage/algebras/orlik_solomon.py +907 -0
- sage/algebras/orlik_terao.py +779 -0
- sage/algebras/steenrod/all.py +7 -0
- sage/algebras/steenrod/steenrod_algebra.py +4258 -0
- sage/algebras/steenrod/steenrod_algebra_bases.py +1179 -0
- sage/algebras/steenrod/steenrod_algebra_misc.py +1167 -0
- sage/algebras/steenrod/steenrod_algebra_mult.py +954 -0
- sage/algebras/weyl_algebra.py +1126 -0
- sage/all__sagemath_modules.py +62 -0
- sage/calculus/all__sagemath_modules.py +19 -0
- sage/calculus/expr.py +205 -0
- sage/calculus/integration.cpython-314-x86_64-linux-musl.so +0 -0
- sage/calculus/integration.pyx +698 -0
- sage/calculus/interpolation.cpython-314-x86_64-linux-musl.so +0 -0
- sage/calculus/interpolation.pxd +13 -0
- sage/calculus/interpolation.pyx +387 -0
- sage/calculus/interpolators.cpython-314-x86_64-linux-musl.so +0 -0
- sage/calculus/interpolators.pyx +326 -0
- sage/calculus/ode.cpython-314-x86_64-linux-musl.so +0 -0
- sage/calculus/ode.pxd +5 -0
- sage/calculus/ode.pyx +610 -0
- sage/calculus/riemann.cpython-314-x86_64-linux-musl.so +0 -0
- sage/calculus/riemann.pyx +1521 -0
- sage/calculus/test_sympy.py +201 -0
- sage/calculus/transforms/all.py +7 -0
- sage/calculus/transforms/dft.py +844 -0
- sage/calculus/transforms/dwt.cpython-314-x86_64-linux-musl.so +0 -0
- sage/calculus/transforms/dwt.pxd +7 -0
- sage/calculus/transforms/dwt.pyx +160 -0
- sage/calculus/transforms/fft.cpython-314-x86_64-linux-musl.so +0 -0
- sage/calculus/transforms/fft.pxd +12 -0
- sage/calculus/transforms/fft.pyx +487 -0
- sage/calculus/wester.py +662 -0
- sage/coding/abstract_code.py +1108 -0
- sage/coding/ag_code.py +868 -0
- sage/coding/ag_code_decoders.cpython-314-x86_64-linux-musl.so +0 -0
- sage/coding/ag_code_decoders.pyx +2639 -0
- sage/coding/all.py +15 -0
- sage/coding/bch_code.py +494 -0
- sage/coding/binary_code.cpython-314-x86_64-linux-musl.so +0 -0
- sage/coding/binary_code.pxd +124 -0
- sage/coding/binary_code.pyx +4139 -0
- sage/coding/bounds_catalog.py +43 -0
- sage/coding/channel.py +819 -0
- sage/coding/channels_catalog.py +29 -0
- sage/coding/code_bounds.py +755 -0
- sage/coding/code_constructions.py +804 -0
- sage/coding/codes_catalog.py +111 -0
- sage/coding/cyclic_code.py +1329 -0
- sage/coding/databases.py +316 -0
- sage/coding/decoder.py +373 -0
- sage/coding/decoders_catalog.py +88 -0
- sage/coding/delsarte_bounds.py +709 -0
- sage/coding/encoder.py +390 -0
- sage/coding/encoders_catalog.py +64 -0
- sage/coding/extended_code.py +468 -0
- sage/coding/gabidulin_code.py +1058 -0
- sage/coding/golay_code.py +404 -0
- sage/coding/goppa_code.py +441 -0
- sage/coding/grs_code.py +2371 -0
- sage/coding/guava.py +107 -0
- sage/coding/guruswami_sudan/all.py +1 -0
- sage/coding/guruswami_sudan/gs_decoder.py +897 -0
- sage/coding/guruswami_sudan/interpolation.py +409 -0
- sage/coding/guruswami_sudan/utils.py +176 -0
- sage/coding/hamming_code.py +176 -0
- sage/coding/information_set_decoder.py +1032 -0
- sage/coding/kasami_codes.cpython-314-x86_64-linux-musl.so +0 -0
- sage/coding/kasami_codes.pyx +351 -0
- sage/coding/linear_code.py +3067 -0
- sage/coding/linear_code_no_metric.py +1354 -0
- sage/coding/linear_rank_metric.py +961 -0
- sage/coding/parity_check_code.py +353 -0
- sage/coding/punctured_code.py +719 -0
- sage/coding/reed_muller_code.py +999 -0
- sage/coding/self_dual_codes.py +942 -0
- sage/coding/source_coding/all.py +2 -0
- sage/coding/source_coding/huffman.py +553 -0
- sage/coding/subfield_subcode.py +423 -0
- sage/coding/two_weight_db.py +399 -0
- sage/combinat/all__sagemath_modules.py +7 -0
- sage/combinat/cartesian_product.py +347 -0
- sage/combinat/family.py +11 -0
- sage/combinat/free_module.py +1977 -0
- sage/combinat/root_system/all.py +147 -0
- sage/combinat/root_system/ambient_space.py +527 -0
- sage/combinat/root_system/associahedron.py +471 -0
- sage/combinat/root_system/braid_move_calculator.py +143 -0
- sage/combinat/root_system/braid_orbit.cpython-314-x86_64-linux-musl.so +0 -0
- sage/combinat/root_system/braid_orbit.pyx +144 -0
- sage/combinat/root_system/branching_rules.py +2301 -0
- sage/combinat/root_system/cartan_matrix.py +1245 -0
- sage/combinat/root_system/cartan_type.py +3069 -0
- sage/combinat/root_system/coxeter_group.py +162 -0
- sage/combinat/root_system/coxeter_matrix.py +1261 -0
- sage/combinat/root_system/coxeter_type.py +681 -0
- sage/combinat/root_system/dynkin_diagram.py +900 -0
- sage/combinat/root_system/extended_affine_weyl_group.py +2993 -0
- sage/combinat/root_system/fundamental_group.py +795 -0
- sage/combinat/root_system/hecke_algebra_representation.py +1203 -0
- sage/combinat/root_system/integrable_representations.py +1227 -0
- sage/combinat/root_system/non_symmetric_macdonald_polynomials.py +1965 -0
- sage/combinat/root_system/pieri_factors.py +1147 -0
- sage/combinat/root_system/plot.py +1615 -0
- sage/combinat/root_system/root_lattice_realization_algebras.py +1214 -0
- sage/combinat/root_system/root_lattice_realizations.py +4628 -0
- sage/combinat/root_system/root_space.py +487 -0
- sage/combinat/root_system/root_system.py +882 -0
- sage/combinat/root_system/type_A.py +348 -0
- sage/combinat/root_system/type_A_affine.py +227 -0
- sage/combinat/root_system/type_A_infinity.py +241 -0
- sage/combinat/root_system/type_B.py +347 -0
- sage/combinat/root_system/type_BC_affine.py +287 -0
- sage/combinat/root_system/type_B_affine.py +216 -0
- sage/combinat/root_system/type_C.py +317 -0
- sage/combinat/root_system/type_C_affine.py +188 -0
- sage/combinat/root_system/type_D.py +357 -0
- sage/combinat/root_system/type_D_affine.py +208 -0
- sage/combinat/root_system/type_E.py +641 -0
- sage/combinat/root_system/type_E_affine.py +231 -0
- sage/combinat/root_system/type_F.py +387 -0
- sage/combinat/root_system/type_F_affine.py +137 -0
- sage/combinat/root_system/type_G.py +293 -0
- sage/combinat/root_system/type_G_affine.py +132 -0
- sage/combinat/root_system/type_H.py +105 -0
- sage/combinat/root_system/type_I.py +110 -0
- sage/combinat/root_system/type_Q.py +150 -0
- sage/combinat/root_system/type_affine.py +509 -0
- sage/combinat/root_system/type_dual.py +704 -0
- sage/combinat/root_system/type_folded.py +301 -0
- sage/combinat/root_system/type_marked.py +748 -0
- sage/combinat/root_system/type_reducible.py +601 -0
- sage/combinat/root_system/type_relabel.py +730 -0
- sage/combinat/root_system/type_super_A.py +837 -0
- sage/combinat/root_system/weight_lattice_realizations.py +1188 -0
- sage/combinat/root_system/weight_space.py +639 -0
- sage/combinat/root_system/weyl_characters.py +2238 -0
- sage/crypto/__init__.py +4 -0
- sage/crypto/all.py +28 -0
- sage/crypto/block_cipher/all.py +7 -0
- sage/crypto/block_cipher/des.py +1065 -0
- sage/crypto/block_cipher/miniaes.py +2171 -0
- sage/crypto/block_cipher/present.py +909 -0
- sage/crypto/block_cipher/sdes.py +1527 -0
- sage/crypto/boolean_function.cpython-314-x86_64-linux-musl.so +0 -0
- sage/crypto/boolean_function.pxd +10 -0
- sage/crypto/boolean_function.pyx +1487 -0
- sage/crypto/cipher.py +78 -0
- sage/crypto/classical.py +3668 -0
- sage/crypto/classical_cipher.py +569 -0
- sage/crypto/cryptosystem.py +387 -0
- sage/crypto/key_exchange/all.py +7 -0
- sage/crypto/key_exchange/catalog.py +24 -0
- sage/crypto/key_exchange/diffie_hellman.py +323 -0
- sage/crypto/key_exchange/key_exchange_scheme.py +107 -0
- sage/crypto/lattice.py +312 -0
- sage/crypto/lfsr.py +295 -0
- sage/crypto/lwe.py +840 -0
- sage/crypto/mq/__init__.py +4 -0
- sage/crypto/mq/mpolynomialsystemgenerator.py +204 -0
- sage/crypto/mq/rijndael_gf.py +2345 -0
- sage/crypto/mq/sbox.py +7 -0
- sage/crypto/mq/sr.py +3344 -0
- sage/crypto/public_key/all.py +5 -0
- sage/crypto/public_key/blum_goldwasser.py +776 -0
- sage/crypto/sbox.cpython-314-x86_64-linux-musl.so +0 -0
- sage/crypto/sbox.pyx +2090 -0
- sage/crypto/sboxes.py +2090 -0
- sage/crypto/stream.py +390 -0
- sage/crypto/stream_cipher.py +297 -0
- sage/crypto/util.py +519 -0
- sage/ext/all__sagemath_modules.py +1 -0
- sage/ext/interpreters/__init__.py +1 -0
- sage/ext/interpreters/all__sagemath_modules.py +2 -0
- sage/ext/interpreters/wrapper_cc.cpython-314-x86_64-linux-musl.so +0 -0
- sage/ext/interpreters/wrapper_cc.pxd +30 -0
- sage/ext/interpreters/wrapper_cc.pyx +252 -0
- sage/ext/interpreters/wrapper_cdf.cpython-314-x86_64-linux-musl.so +0 -0
- sage/ext/interpreters/wrapper_cdf.pxd +26 -0
- sage/ext/interpreters/wrapper_cdf.pyx +245 -0
- sage/ext/interpreters/wrapper_rdf.cpython-314-x86_64-linux-musl.so +0 -0
- sage/ext/interpreters/wrapper_rdf.pxd +23 -0
- sage/ext/interpreters/wrapper_rdf.pyx +221 -0
- sage/ext/interpreters/wrapper_rr.cpython-314-x86_64-linux-musl.so +0 -0
- sage/ext/interpreters/wrapper_rr.pxd +28 -0
- sage/ext/interpreters/wrapper_rr.pyx +335 -0
- sage/geometry/all__sagemath_modules.py +5 -0
- sage/geometry/toric_lattice.py +1745 -0
- sage/geometry/toric_lattice_element.cpython-314-x86_64-linux-musl.so +0 -0
- sage/geometry/toric_lattice_element.pyx +432 -0
- sage/groups/abelian_gps/abelian_group.py +1925 -0
- sage/groups/abelian_gps/abelian_group_element.py +164 -0
- sage/groups/abelian_gps/all__sagemath_modules.py +5 -0
- sage/groups/abelian_gps/dual_abelian_group.py +421 -0
- sage/groups/abelian_gps/dual_abelian_group_element.py +179 -0
- sage/groups/abelian_gps/element_base.py +341 -0
- sage/groups/abelian_gps/values.py +488 -0
- sage/groups/additive_abelian/additive_abelian_group.py +476 -0
- sage/groups/additive_abelian/additive_abelian_wrapper.py +857 -0
- sage/groups/additive_abelian/all.py +4 -0
- sage/groups/additive_abelian/qmodnz.py +231 -0
- sage/groups/additive_abelian/qmodnz_element.py +349 -0
- sage/groups/affine_gps/affine_group.py +535 -0
- sage/groups/affine_gps/all.py +1 -0
- sage/groups/affine_gps/catalog.py +17 -0
- sage/groups/affine_gps/euclidean_group.py +246 -0
- sage/groups/affine_gps/group_element.py +562 -0
- sage/groups/all__sagemath_modules.py +12 -0
- sage/groups/galois_group.py +479 -0
- sage/groups/matrix_gps/all.py +4 -0
- sage/groups/matrix_gps/all__sagemath_modules.py +13 -0
- sage/groups/matrix_gps/catalog.py +26 -0
- sage/groups/matrix_gps/coxeter_group.py +927 -0
- sage/groups/matrix_gps/finitely_generated.py +487 -0
- sage/groups/matrix_gps/group_element.cpython-314-x86_64-linux-musl.so +0 -0
- sage/groups/matrix_gps/group_element.pxd +11 -0
- sage/groups/matrix_gps/group_element.pyx +431 -0
- sage/groups/matrix_gps/linear.py +440 -0
- sage/groups/matrix_gps/matrix_group.py +617 -0
- sage/groups/matrix_gps/named_group.py +296 -0
- sage/groups/matrix_gps/orthogonal.py +544 -0
- sage/groups/matrix_gps/symplectic.py +251 -0
- sage/groups/matrix_gps/unitary.py +436 -0
- sage/groups/misc_gps/all__sagemath_modules.py +1 -0
- sage/groups/misc_gps/argument_groups.py +1905 -0
- sage/groups/misc_gps/imaginary_groups.py +479 -0
- sage/groups/perm_gps/all__sagemath_modules.py +1 -0
- sage/groups/perm_gps/partn_ref/all__sagemath_modules.py +1 -0
- sage/groups/perm_gps/partn_ref/refinement_binary.cpython-314-x86_64-linux-musl.so +0 -0
- sage/groups/perm_gps/partn_ref/refinement_binary.pxd +41 -0
- sage/groups/perm_gps/partn_ref/refinement_binary.pyx +1167 -0
- sage/groups/perm_gps/partn_ref/refinement_matrices.cpython-314-x86_64-linux-musl.so +0 -0
- sage/groups/perm_gps/partn_ref/refinement_matrices.pxd +31 -0
- sage/groups/perm_gps/partn_ref/refinement_matrices.pyx +385 -0
- sage/homology/algebraic_topological_model.py +595 -0
- sage/homology/all.py +2 -0
- sage/homology/all__sagemath_modules.py +8 -0
- sage/homology/chain_complex.py +2148 -0
- sage/homology/chain_complex_homspace.py +165 -0
- sage/homology/chain_complex_morphism.py +629 -0
- sage/homology/chain_homotopy.py +604 -0
- sage/homology/chains.py +653 -0
- sage/homology/free_resolution.py +923 -0
- sage/homology/graded_resolution.py +567 -0
- sage/homology/hochschild_complex.py +756 -0
- sage/homology/homology_group.py +188 -0
- sage/homology/homology_morphism.py +422 -0
- sage/homology/homology_vector_space_with_basis.py +1454 -0
- sage/homology/koszul_complex.py +169 -0
- sage/homology/matrix_utils.py +205 -0
- sage/libs/all__sagemath_modules.py +1 -0
- sage/libs/gsl/__init__.py +1 -0
- sage/libs/gsl/airy.pxd +56 -0
- sage/libs/gsl/all.pxd +66 -0
- sage/libs/gsl/array.cpython-314-x86_64-linux-musl.so +0 -0
- sage/libs/gsl/array.pxd +5 -0
- sage/libs/gsl/array.pyx +102 -0
- sage/libs/gsl/bessel.pxd +208 -0
- sage/libs/gsl/blas.pxd +116 -0
- sage/libs/gsl/blas_types.pxd +34 -0
- sage/libs/gsl/block.pxd +52 -0
- sage/libs/gsl/chebyshev.pxd +37 -0
- sage/libs/gsl/clausen.pxd +12 -0
- sage/libs/gsl/combination.pxd +47 -0
- sage/libs/gsl/complex.pxd +151 -0
- sage/libs/gsl/coulomb.pxd +30 -0
- sage/libs/gsl/coupling.pxd +21 -0
- sage/libs/gsl/dawson.pxd +12 -0
- sage/libs/gsl/debye.pxd +24 -0
- sage/libs/gsl/dilog.pxd +14 -0
- sage/libs/gsl/eigen.pxd +46 -0
- sage/libs/gsl/elementary.pxd +12 -0
- sage/libs/gsl/ellint.pxd +48 -0
- sage/libs/gsl/elljac.pxd +8 -0
- sage/libs/gsl/erf.pxd +32 -0
- sage/libs/gsl/errno.pxd +26 -0
- sage/libs/gsl/exp.pxd +44 -0
- sage/libs/gsl/expint.pxd +44 -0
- sage/libs/gsl/fermi_dirac.pxd +44 -0
- sage/libs/gsl/fft.pxd +121 -0
- sage/libs/gsl/fit.pxd +50 -0
- sage/libs/gsl/gamma.pxd +94 -0
- sage/libs/gsl/gegenbauer.pxd +26 -0
- sage/libs/gsl/histogram.pxd +176 -0
- sage/libs/gsl/hyperg.pxd +52 -0
- sage/libs/gsl/integration.pxd +69 -0
- sage/libs/gsl/interp.pxd +109 -0
- sage/libs/gsl/laguerre.pxd +24 -0
- sage/libs/gsl/lambert.pxd +16 -0
- sage/libs/gsl/legendre.pxd +90 -0
- sage/libs/gsl/linalg.pxd +185 -0
- sage/libs/gsl/log.pxd +26 -0
- sage/libs/gsl/math.pxd +43 -0
- sage/libs/gsl/matrix.pxd +143 -0
- sage/libs/gsl/matrix_complex.pxd +130 -0
- sage/libs/gsl/min.pxd +67 -0
- sage/libs/gsl/monte.pxd +56 -0
- sage/libs/gsl/ntuple.pxd +32 -0
- sage/libs/gsl/odeiv.pxd +70 -0
- sage/libs/gsl/permutation.pxd +78 -0
- sage/libs/gsl/poly.pxd +40 -0
- sage/libs/gsl/pow_int.pxd +12 -0
- sage/libs/gsl/psi.pxd +28 -0
- sage/libs/gsl/qrng.pxd +29 -0
- sage/libs/gsl/random.pxd +257 -0
- sage/libs/gsl/rng.pxd +100 -0
- sage/libs/gsl/roots.pxd +72 -0
- sage/libs/gsl/sort.pxd +36 -0
- sage/libs/gsl/statistics.pxd +59 -0
- sage/libs/gsl/sum.pxd +55 -0
- sage/libs/gsl/synchrotron.pxd +16 -0
- sage/libs/gsl/transport.pxd +24 -0
- sage/libs/gsl/trig.pxd +58 -0
- sage/libs/gsl/types.pxd +137 -0
- sage/libs/gsl/vector.pxd +101 -0
- sage/libs/gsl/vector_complex.pxd +83 -0
- sage/libs/gsl/wavelet.pxd +49 -0
- sage/libs/gsl/zeta.pxd +28 -0
- sage/libs/mpc/__init__.pxd +114 -0
- sage/libs/mpc/types.pxd +28 -0
- sage/libs/mpfr/__init__.pxd +299 -0
- sage/libs/mpfr/types.pxd +26 -0
- sage/libs/mpmath/__init__.py +1 -0
- sage/libs/mpmath/all.py +27 -0
- sage/libs/mpmath/all__sagemath_modules.py +1 -0
- sage/libs/mpmath/utils.cpython-314-x86_64-linux-musl.so +0 -0
- sage/libs/mpmath/utils.pxd +4 -0
- sage/libs/mpmath/utils.pyx +319 -0
- sage/matrix/action.cpython-314-x86_64-linux-musl.so +0 -0
- sage/matrix/action.pxd +26 -0
- sage/matrix/action.pyx +596 -0
- sage/matrix/all.py +9 -0
- sage/matrix/args.cpython-314-x86_64-linux-musl.so +0 -0
- sage/matrix/args.pxd +144 -0
- sage/matrix/args.pyx +1668 -0
- sage/matrix/benchmark.py +1258 -0
- sage/matrix/berlekamp_massey.py +95 -0
- sage/matrix/compute_J_ideal.py +926 -0
- sage/matrix/constructor.cpython-314-x86_64-linux-musl.so +0 -0
- sage/matrix/constructor.pyx +750 -0
- sage/matrix/docs.py +430 -0
- sage/matrix/echelon_matrix.cpython-314-x86_64-linux-musl.so +0 -0
- sage/matrix/echelon_matrix.pyx +155 -0
- sage/matrix/matrix.pxd +2 -0
- sage/matrix/matrix0.cpython-314-x86_64-linux-musl.so +0 -0
- sage/matrix/matrix0.pxd +68 -0
- sage/matrix/matrix0.pyx +6324 -0
- sage/matrix/matrix1.cpython-314-x86_64-linux-musl.so +0 -0
- sage/matrix/matrix1.pxd +8 -0
- sage/matrix/matrix1.pyx +2851 -0
- sage/matrix/matrix2.cpython-314-x86_64-linux-musl.so +0 -0
- sage/matrix/matrix2.pxd +25 -0
- sage/matrix/matrix2.pyx +20181 -0
- sage/matrix/matrix_cdv.cpython-314-x86_64-linux-musl.so +0 -0
- sage/matrix/matrix_cdv.pxd +4 -0
- sage/matrix/matrix_cdv.pyx +93 -0
- sage/matrix/matrix_complex_double_dense.cpython-314-x86_64-linux-musl.so +0 -0
- sage/matrix/matrix_complex_double_dense.pxd +5 -0
- sage/matrix/matrix_complex_double_dense.pyx +98 -0
- sage/matrix/matrix_dense.cpython-314-x86_64-linux-musl.so +0 -0
- sage/matrix/matrix_dense.pxd +5 -0
- sage/matrix/matrix_dense.pyx +343 -0
- sage/matrix/matrix_domain_dense.pxd +5 -0
- sage/matrix/matrix_domain_sparse.pxd +5 -0
- sage/matrix/matrix_double_dense.cpython-314-x86_64-linux-musl.so +0 -0
- sage/matrix/matrix_double_dense.pxd +7 -0
- sage/matrix/matrix_double_dense.pyx +3906 -0
- sage/matrix/matrix_double_sparse.cpython-314-x86_64-linux-musl.so +0 -0
- sage/matrix/matrix_double_sparse.pxd +6 -0
- sage/matrix/matrix_double_sparse.pyx +248 -0
- sage/matrix/matrix_generic_dense.cpython-314-x86_64-linux-musl.so +0 -0
- sage/matrix/matrix_generic_dense.pxd +7 -0
- sage/matrix/matrix_generic_dense.pyx +354 -0
- sage/matrix/matrix_generic_sparse.cpython-314-x86_64-linux-musl.so +0 -0
- sage/matrix/matrix_generic_sparse.pxd +7 -0
- sage/matrix/matrix_generic_sparse.pyx +461 -0
- sage/matrix/matrix_laurent_mpolynomial_dense.cpython-314-x86_64-linux-musl.so +0 -0
- sage/matrix/matrix_laurent_mpolynomial_dense.pxd +5 -0
- sage/matrix/matrix_laurent_mpolynomial_dense.pyx +115 -0
- sage/matrix/matrix_misc.py +313 -0
- sage/matrix/matrix_numpy_dense.cpython-314-x86_64-linux-musl.so +0 -0
- sage/matrix/matrix_numpy_dense.pxd +14 -0
- sage/matrix/matrix_numpy_dense.pyx +450 -0
- sage/matrix/matrix_numpy_integer_dense.cpython-314-x86_64-linux-musl.so +0 -0
- sage/matrix/matrix_numpy_integer_dense.pxd +7 -0
- sage/matrix/matrix_numpy_integer_dense.pyx +59 -0
- sage/matrix/matrix_polynomial_dense.cpython-314-x86_64-linux-musl.so +0 -0
- sage/matrix/matrix_polynomial_dense.pxd +5 -0
- sage/matrix/matrix_polynomial_dense.pyx +5341 -0
- sage/matrix/matrix_real_double_dense.cpython-314-x86_64-linux-musl.so +0 -0
- sage/matrix/matrix_real_double_dense.pxd +7 -0
- sage/matrix/matrix_real_double_dense.pyx +122 -0
- sage/matrix/matrix_space.py +2848 -0
- sage/matrix/matrix_sparse.cpython-314-x86_64-linux-musl.so +0 -0
- sage/matrix/matrix_sparse.pxd +5 -0
- sage/matrix/matrix_sparse.pyx +1222 -0
- sage/matrix/matrix_window.cpython-314-x86_64-linux-musl.so +0 -0
- sage/matrix/matrix_window.pxd +37 -0
- sage/matrix/matrix_window.pyx +242 -0
- sage/matrix/misc_mpfr.cpython-314-x86_64-linux-musl.so +0 -0
- sage/matrix/misc_mpfr.pyx +80 -0
- sage/matrix/operation_table.py +1182 -0
- sage/matrix/special.py +3666 -0
- sage/matrix/strassen.cpython-314-x86_64-linux-musl.so +0 -0
- sage/matrix/strassen.pyx +851 -0
- sage/matrix/symplectic_basis.py +541 -0
- sage/matrix/template.pxd +6 -0
- sage/matrix/tests.py +71 -0
- sage/matroids/advanced.py +77 -0
- sage/matroids/all.py +13 -0
- sage/matroids/basis_exchange_matroid.cpython-314-x86_64-linux-musl.so +0 -0
- sage/matroids/basis_exchange_matroid.pxd +96 -0
- sage/matroids/basis_exchange_matroid.pyx +2344 -0
- sage/matroids/basis_matroid.cpython-314-x86_64-linux-musl.so +0 -0
- sage/matroids/basis_matroid.pxd +45 -0
- sage/matroids/basis_matroid.pyx +1217 -0
- sage/matroids/catalog.py +44 -0
- sage/matroids/chow_ring.py +473 -0
- sage/matroids/chow_ring_ideal.py +849 -0
- sage/matroids/circuit_closures_matroid.cpython-314-x86_64-linux-musl.so +0 -0
- sage/matroids/circuit_closures_matroid.pxd +16 -0
- sage/matroids/circuit_closures_matroid.pyx +559 -0
- sage/matroids/circuits_matroid.cpython-314-x86_64-linux-musl.so +0 -0
- sage/matroids/circuits_matroid.pxd +38 -0
- sage/matroids/circuits_matroid.pyx +947 -0
- sage/matroids/constructor.py +1086 -0
- sage/matroids/database_collections.py +365 -0
- sage/matroids/database_matroids.py +5338 -0
- sage/matroids/dual_matroid.py +583 -0
- sage/matroids/extension.cpython-314-x86_64-linux-musl.so +0 -0
- sage/matroids/extension.pxd +34 -0
- sage/matroids/extension.pyx +519 -0
- sage/matroids/flats_matroid.cpython-314-x86_64-linux-musl.so +0 -0
- sage/matroids/flats_matroid.pxd +28 -0
- sage/matroids/flats_matroid.pyx +715 -0
- sage/matroids/gammoid.py +600 -0
- sage/matroids/graphic_matroid.cpython-314-x86_64-linux-musl.so +0 -0
- sage/matroids/graphic_matroid.pxd +39 -0
- sage/matroids/graphic_matroid.pyx +2024 -0
- sage/matroids/lean_matrix.cpython-314-x86_64-linux-musl.so +0 -0
- sage/matroids/lean_matrix.pxd +126 -0
- sage/matroids/lean_matrix.pyx +3667 -0
- sage/matroids/linear_matroid.cpython-314-x86_64-linux-musl.so +0 -0
- sage/matroids/linear_matroid.pxd +180 -0
- sage/matroids/linear_matroid.pyx +6649 -0
- sage/matroids/matroid.cpython-314-x86_64-linux-musl.so +0 -0
- sage/matroids/matroid.pxd +243 -0
- sage/matroids/matroid.pyx +8759 -0
- sage/matroids/matroids_catalog.py +190 -0
- sage/matroids/matroids_plot_helpers.py +890 -0
- sage/matroids/minor_matroid.py +480 -0
- sage/matroids/minorfix.h +9 -0
- sage/matroids/named_matroids.py +5 -0
- sage/matroids/rank_matroid.py +268 -0
- sage/matroids/set_system.cpython-314-x86_64-linux-musl.so +0 -0
- sage/matroids/set_system.pxd +38 -0
- sage/matroids/set_system.pyx +800 -0
- sage/matroids/transversal_matroid.cpython-314-x86_64-linux-musl.so +0 -0
- sage/matroids/transversal_matroid.pxd +14 -0
- sage/matroids/transversal_matroid.pyx +893 -0
- sage/matroids/union_matroid.cpython-314-x86_64-linux-musl.so +0 -0
- sage/matroids/union_matroid.pxd +20 -0
- sage/matroids/union_matroid.pyx +331 -0
- sage/matroids/unpickling.cpython-314-x86_64-linux-musl.so +0 -0
- sage/matroids/unpickling.pyx +843 -0
- sage/matroids/utilities.py +809 -0
- sage/misc/all__sagemath_modules.py +20 -0
- sage/misc/c3.cpython-314-x86_64-linux-musl.so +0 -0
- sage/misc/c3.pyx +238 -0
- sage/misc/compat.py +87 -0
- sage/misc/element_with_label.py +173 -0
- sage/misc/func_persist.py +79 -0
- sage/misc/pickle_old.cpython-314-x86_64-linux-musl.so +0 -0
- sage/misc/pickle_old.pyx +19 -0
- sage/misc/proof.py +7 -0
- sage/misc/replace_dot_all.py +472 -0
- sage/misc/sagedoc_conf.py +168 -0
- sage/misc/sphinxify.py +167 -0
- sage/misc/test_class_pickling.py +85 -0
- sage/modules/all.py +42 -0
- sage/modules/complex_double_vector.py +25 -0
- sage/modules/diamond_cutting.py +380 -0
- sage/modules/fg_pid/all.py +1 -0
- sage/modules/fg_pid/fgp_element.py +456 -0
- sage/modules/fg_pid/fgp_module.py +2091 -0
- sage/modules/fg_pid/fgp_morphism.py +550 -0
- sage/modules/filtered_vector_space.py +1271 -0
- sage/modules/finite_submodule_iter.cpython-314-x86_64-linux-musl.so +0 -0
- sage/modules/finite_submodule_iter.pxd +27 -0
- sage/modules/finite_submodule_iter.pyx +452 -0
- sage/modules/fp_graded/all.py +1 -0
- sage/modules/fp_graded/element.py +346 -0
- sage/modules/fp_graded/free_element.py +298 -0
- sage/modules/fp_graded/free_homspace.py +53 -0
- sage/modules/fp_graded/free_module.py +1060 -0
- sage/modules/fp_graded/free_morphism.py +217 -0
- sage/modules/fp_graded/homspace.py +563 -0
- sage/modules/fp_graded/module.py +1340 -0
- sage/modules/fp_graded/morphism.py +1990 -0
- sage/modules/fp_graded/steenrod/all.py +1 -0
- sage/modules/fp_graded/steenrod/homspace.py +65 -0
- sage/modules/fp_graded/steenrod/module.py +477 -0
- sage/modules/fp_graded/steenrod/morphism.py +404 -0
- sage/modules/fp_graded/steenrod/profile.py +241 -0
- sage/modules/free_module.py +8447 -0
- sage/modules/free_module_element.cpython-314-x86_64-linux-musl.so +0 -0
- sage/modules/free_module_element.pxd +22 -0
- sage/modules/free_module_element.pyx +5445 -0
- sage/modules/free_module_homspace.py +369 -0
- sage/modules/free_module_integer.py +896 -0
- sage/modules/free_module_morphism.py +823 -0
- sage/modules/free_module_pseudohomspace.py +352 -0
- sage/modules/free_module_pseudomorphism.py +578 -0
- sage/modules/free_quadratic_module.py +1706 -0
- sage/modules/free_quadratic_module_integer_symmetric.py +1790 -0
- sage/modules/matrix_morphism.py +1745 -0
- sage/modules/misc.py +103 -0
- sage/modules/module_functors.py +192 -0
- sage/modules/multi_filtered_vector_space.py +719 -0
- sage/modules/ore_module.py +2208 -0
- sage/modules/ore_module_element.py +178 -0
- sage/modules/ore_module_homspace.py +147 -0
- sage/modules/ore_module_morphism.py +968 -0
- sage/modules/quotient_module.py +699 -0
- sage/modules/real_double_vector.py +22 -0
- sage/modules/submodule.py +255 -0
- sage/modules/tensor_operations.py +567 -0
- sage/modules/torsion_quadratic_module.py +1352 -0
- sage/modules/tutorial_free_modules.py +248 -0
- sage/modules/vector_complex_double_dense.cpython-314-x86_64-linux-musl.so +0 -0
- sage/modules/vector_complex_double_dense.pxd +6 -0
- sage/modules/vector_complex_double_dense.pyx +117 -0
- sage/modules/vector_double_dense.cpython-314-x86_64-linux-musl.so +0 -0
- sage/modules/vector_double_dense.pxd +6 -0
- sage/modules/vector_double_dense.pyx +604 -0
- sage/modules/vector_integer_dense.cpython-314-x86_64-linux-musl.so +0 -0
- sage/modules/vector_integer_dense.pxd +15 -0
- sage/modules/vector_integer_dense.pyx +361 -0
- sage/modules/vector_integer_sparse.cpython-314-x86_64-linux-musl.so +0 -0
- sage/modules/vector_integer_sparse.pxd +29 -0
- sage/modules/vector_integer_sparse.pyx +406 -0
- sage/modules/vector_modn_dense.cpython-314-x86_64-linux-musl.so +0 -0
- sage/modules/vector_modn_dense.pxd +12 -0
- sage/modules/vector_modn_dense.pyx +394 -0
- sage/modules/vector_modn_sparse.cpython-314-x86_64-linux-musl.so +0 -0
- sage/modules/vector_modn_sparse.pxd +21 -0
- sage/modules/vector_modn_sparse.pyx +298 -0
- sage/modules/vector_numpy_dense.cpython-314-x86_64-linux-musl.so +0 -0
- sage/modules/vector_numpy_dense.pxd +15 -0
- sage/modules/vector_numpy_dense.pyx +304 -0
- sage/modules/vector_numpy_integer_dense.cpython-314-x86_64-linux-musl.so +0 -0
- sage/modules/vector_numpy_integer_dense.pxd +7 -0
- sage/modules/vector_numpy_integer_dense.pyx +54 -0
- sage/modules/vector_rational_dense.cpython-314-x86_64-linux-musl.so +0 -0
- sage/modules/vector_rational_dense.pxd +15 -0
- sage/modules/vector_rational_dense.pyx +387 -0
- sage/modules/vector_rational_sparse.cpython-314-x86_64-linux-musl.so +0 -0
- sage/modules/vector_rational_sparse.pxd +30 -0
- sage/modules/vector_rational_sparse.pyx +413 -0
- sage/modules/vector_real_double_dense.cpython-314-x86_64-linux-musl.so +0 -0
- sage/modules/vector_real_double_dense.pxd +6 -0
- sage/modules/vector_real_double_dense.pyx +126 -0
- sage/modules/vector_space_homspace.py +430 -0
- sage/modules/vector_space_morphism.py +989 -0
- sage/modules/with_basis/all.py +15 -0
- sage/modules/with_basis/cell_module.py +494 -0
- sage/modules/with_basis/indexed_element.cpython-314-x86_64-linux-musl.so +0 -0
- sage/modules/with_basis/indexed_element.pxd +13 -0
- sage/modules/with_basis/indexed_element.pyx +1058 -0
- sage/modules/with_basis/invariant.py +1075 -0
- sage/modules/with_basis/morphism.py +1636 -0
- sage/modules/with_basis/representation.py +2939 -0
- sage/modules/with_basis/subquotient.py +685 -0
- sage/numerical/all__sagemath_modules.py +6 -0
- sage/numerical/gauss_legendre.cpython-314-x86_64-linux-musl.so +0 -0
- sage/numerical/gauss_legendre.pyx +381 -0
- sage/numerical/optimize.py +910 -0
- sage/probability/all.py +10 -0
- sage/probability/probability_distribution.cpython-314-x86_64-linux-musl.so +0 -0
- sage/probability/probability_distribution.pyx +1242 -0
- sage/probability/random_variable.py +411 -0
- sage/quadratic_forms/all.py +4 -0
- sage/quadratic_forms/all__sagemath_modules.py +15 -0
- sage/quadratic_forms/binary_qf.py +2042 -0
- sage/quadratic_forms/bqf_class_group.py +748 -0
- sage/quadratic_forms/constructions.py +93 -0
- sage/quadratic_forms/count_local_2.cpython-314-x86_64-linux-musl.so +0 -0
- sage/quadratic_forms/count_local_2.pyx +365 -0
- sage/quadratic_forms/extras.py +195 -0
- sage/quadratic_forms/quadratic_form.py +1753 -0
- sage/quadratic_forms/quadratic_form__count_local_2.py +221 -0
- sage/quadratic_forms/quadratic_form__equivalence_testing.py +708 -0
- sage/quadratic_forms/quadratic_form__evaluate.cpython-314-x86_64-linux-musl.so +0 -0
- sage/quadratic_forms/quadratic_form__evaluate.pyx +139 -0
- sage/quadratic_forms/quadratic_form__local_density_congruence.py +977 -0
- sage/quadratic_forms/quadratic_form__local_field_invariants.py +1072 -0
- sage/quadratic_forms/quadratic_form__neighbors.py +424 -0
- sage/quadratic_forms/quadratic_form__reduction_theory.py +488 -0
- sage/quadratic_forms/quadratic_form__split_local_covering.py +416 -0
- sage/quadratic_forms/quadratic_form__ternary_Tornaria.py +657 -0
- sage/quadratic_forms/quadratic_form__theta.py +352 -0
- sage/quadratic_forms/quadratic_form__variable_substitutions.py +370 -0
- sage/quadratic_forms/random_quadraticform.py +209 -0
- sage/quadratic_forms/ternary.cpython-314-x86_64-linux-musl.so +0 -0
- sage/quadratic_forms/ternary.pyx +1154 -0
- sage/quadratic_forms/ternary_qf.py +2027 -0
- sage/rings/all__sagemath_modules.py +28 -0
- sage/rings/asymptotic/all__sagemath_modules.py +1 -0
- sage/rings/asymptotic/misc.py +1252 -0
- sage/rings/cc.py +4 -0
- sage/rings/cfinite_sequence.py +1306 -0
- sage/rings/complex_conversion.cpython-314-x86_64-linux-musl.so +0 -0
- sage/rings/complex_conversion.pxd +8 -0
- sage/rings/complex_conversion.pyx +23 -0
- sage/rings/complex_double.cpython-314-x86_64-linux-musl.so +0 -0
- sage/rings/complex_double.pxd +21 -0
- sage/rings/complex_double.pyx +2654 -0
- sage/rings/complex_mpc.cpython-314-x86_64-linux-musl.so +0 -0
- sage/rings/complex_mpc.pxd +21 -0
- sage/rings/complex_mpc.pyx +2576 -0
- sage/rings/complex_mpfr.cpython-314-x86_64-linux-musl.so +0 -0
- sage/rings/complex_mpfr.pxd +18 -0
- sage/rings/complex_mpfr.pyx +3602 -0
- sage/rings/derivation.py +2334 -0
- sage/rings/finite_rings/all__sagemath_modules.py +1 -0
- sage/rings/finite_rings/maps_finite_field.py +191 -0
- sage/rings/function_field/all__sagemath_modules.py +8 -0
- sage/rings/function_field/derivations.py +102 -0
- sage/rings/function_field/derivations_rational.py +132 -0
- sage/rings/function_field/differential.py +853 -0
- sage/rings/function_field/divisor.py +1107 -0
- sage/rings/function_field/drinfeld_modules/action.py +199 -0
- sage/rings/function_field/drinfeld_modules/all.py +1 -0
- sage/rings/function_field/drinfeld_modules/charzero_drinfeld_module.py +673 -0
- sage/rings/function_field/drinfeld_modules/drinfeld_module.py +2087 -0
- sage/rings/function_field/drinfeld_modules/finite_drinfeld_module.py +1131 -0
- sage/rings/function_field/drinfeld_modules/homset.py +420 -0
- sage/rings/function_field/drinfeld_modules/morphism.py +820 -0
- sage/rings/function_field/hermite_form_polynomial.cpython-314-x86_64-linux-musl.so +0 -0
- sage/rings/function_field/hermite_form_polynomial.pyx +188 -0
- sage/rings/function_field/khuri_makdisi.cpython-314-x86_64-linux-musl.so +0 -0
- sage/rings/function_field/khuri_makdisi.pyx +935 -0
- sage/rings/invariants/all.py +4 -0
- sage/rings/invariants/invariant_theory.py +4597 -0
- sage/rings/invariants/reconstruction.py +395 -0
- sage/rings/polynomial/all__sagemath_modules.py +17 -0
- sage/rings/polynomial/integer_valued_polynomials.py +1230 -0
- sage/rings/polynomial/laurent_polynomial_mpair.cpython-314-x86_64-linux-musl.so +0 -0
- sage/rings/polynomial/laurent_polynomial_mpair.pxd +15 -0
- sage/rings/polynomial/laurent_polynomial_mpair.pyx +2023 -0
- sage/rings/polynomial/ore_function_element.py +952 -0
- sage/rings/polynomial/ore_function_field.py +1028 -0
- sage/rings/polynomial/ore_polynomial_element.cpython-314-x86_64-linux-musl.so +0 -0
- sage/rings/polynomial/ore_polynomial_element.pxd +48 -0
- sage/rings/polynomial/ore_polynomial_element.pyx +3145 -0
- sage/rings/polynomial/ore_polynomial_ring.py +1334 -0
- sage/rings/polynomial/polynomial_real_mpfr_dense.cpython-314-x86_64-linux-musl.so +0 -0
- sage/rings/polynomial/polynomial_real_mpfr_dense.pyx +788 -0
- sage/rings/polynomial/q_integer_valued_polynomials.py +1264 -0
- sage/rings/polynomial/skew_polynomial_element.cpython-314-x86_64-linux-musl.so +0 -0
- sage/rings/polynomial/skew_polynomial_element.pxd +9 -0
- sage/rings/polynomial/skew_polynomial_element.pyx +684 -0
- sage/rings/polynomial/skew_polynomial_finite_field.cpython-314-x86_64-linux-musl.so +0 -0
- sage/rings/polynomial/skew_polynomial_finite_field.pxd +19 -0
- sage/rings/polynomial/skew_polynomial_finite_field.pyx +1093 -0
- sage/rings/polynomial/skew_polynomial_finite_order.cpython-314-x86_64-linux-musl.so +0 -0
- sage/rings/polynomial/skew_polynomial_finite_order.pxd +10 -0
- sage/rings/polynomial/skew_polynomial_finite_order.pyx +567 -0
- sage/rings/polynomial/skew_polynomial_ring.py +908 -0
- sage/rings/real_double_element_gsl.cpython-314-x86_64-linux-musl.so +0 -0
- sage/rings/real_double_element_gsl.pxd +8 -0
- sage/rings/real_double_element_gsl.pyx +794 -0
- sage/rings/real_field.py +58 -0
- sage/rings/real_mpfr.cpython-314-x86_64-linux-musl.so +0 -0
- sage/rings/real_mpfr.pxd +29 -0
- sage/rings/real_mpfr.pyx +6122 -0
- sage/rings/ring_extension.cpython-314-x86_64-linux-musl.so +0 -0
- sage/rings/ring_extension.pxd +42 -0
- sage/rings/ring_extension.pyx +2779 -0
- sage/rings/ring_extension_conversion.cpython-314-x86_64-linux-musl.so +0 -0
- sage/rings/ring_extension_conversion.pxd +16 -0
- sage/rings/ring_extension_conversion.pyx +462 -0
- sage/rings/ring_extension_element.cpython-314-x86_64-linux-musl.so +0 -0
- sage/rings/ring_extension_element.pxd +21 -0
- sage/rings/ring_extension_element.pyx +1635 -0
- sage/rings/ring_extension_homset.py +64 -0
- sage/rings/ring_extension_morphism.cpython-314-x86_64-linux-musl.so +0 -0
- sage/rings/ring_extension_morphism.pxd +35 -0
- sage/rings/ring_extension_morphism.pyx +920 -0
- sage/schemes/all__sagemath_modules.py +1 -0
- sage/schemes/projective/all__sagemath_modules.py +1 -0
- sage/schemes/projective/coherent_sheaf.py +300 -0
- sage/schemes/projective/cohomology.py +510 -0
- sage/stats/all.py +15 -0
- sage/stats/basic_stats.py +489 -0
- sage/stats/distributions/all.py +7 -0
- sage/stats/distributions/catalog.py +34 -0
- sage/stats/distributions/dgs.h +50 -0
- sage/stats/distributions/dgs.pxd +111 -0
- sage/stats/distributions/dgs_bern.h +400 -0
- sage/stats/distributions/dgs_gauss.h +614 -0
- sage/stats/distributions/dgs_misc.h +104 -0
- sage/stats/distributions/discrete_gaussian_integer.cpython-314-x86_64-linux-musl.so +0 -0
- sage/stats/distributions/discrete_gaussian_integer.pxd +14 -0
- sage/stats/distributions/discrete_gaussian_integer.pyx +498 -0
- sage/stats/distributions/discrete_gaussian_lattice.py +908 -0
- sage/stats/distributions/discrete_gaussian_polynomial.py +141 -0
- sage/stats/hmm/all.py +15 -0
- sage/stats/hmm/chmm.cpython-314-x86_64-linux-musl.so +0 -0
- sage/stats/hmm/chmm.pyx +1595 -0
- sage/stats/hmm/distributions.cpython-314-x86_64-linux-musl.so +0 -0
- sage/stats/hmm/distributions.pxd +29 -0
- sage/stats/hmm/distributions.pyx +531 -0
- sage/stats/hmm/hmm.cpython-314-x86_64-linux-musl.so +0 -0
- sage/stats/hmm/hmm.pxd +17 -0
- sage/stats/hmm/hmm.pyx +1388 -0
- sage/stats/hmm/util.cpython-314-x86_64-linux-musl.so +0 -0
- sage/stats/hmm/util.pxd +7 -0
- sage/stats/hmm/util.pyx +165 -0
- sage/stats/intlist.cpython-314-x86_64-linux-musl.so +0 -0
- sage/stats/intlist.pxd +14 -0
- sage/stats/intlist.pyx +588 -0
- sage/stats/r.py +49 -0
- sage/stats/time_series.cpython-314-x86_64-linux-musl.so +0 -0
- sage/stats/time_series.pxd +6 -0
- sage/stats/time_series.pyx +2546 -0
- sage/tensor/all.py +2 -0
- sage/tensor/modules/all.py +8 -0
- sage/tensor/modules/alternating_contr_tensor.py +761 -0
- sage/tensor/modules/comp.py +5598 -0
- sage/tensor/modules/ext_pow_free_module.py +824 -0
- sage/tensor/modules/finite_rank_free_module.py +3589 -0
- sage/tensor/modules/format_utilities.py +333 -0
- sage/tensor/modules/free_module_alt_form.py +858 -0
- sage/tensor/modules/free_module_automorphism.py +1207 -0
- sage/tensor/modules/free_module_basis.py +1074 -0
- sage/tensor/modules/free_module_element.py +284 -0
- sage/tensor/modules/free_module_homset.py +652 -0
- sage/tensor/modules/free_module_linear_group.py +564 -0
- sage/tensor/modules/free_module_morphism.py +1581 -0
- sage/tensor/modules/free_module_tensor.py +3289 -0
- sage/tensor/modules/reflexive_module.py +386 -0
- sage/tensor/modules/tensor_free_module.py +780 -0
- sage/tensor/modules/tensor_free_submodule.py +538 -0
- sage/tensor/modules/tensor_free_submodule_basis.py +140 -0
- sage/tensor/modules/tensor_with_indices.py +1043 -0
|
@@ -0,0 +1,908 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-modules
|
|
2
|
+
r"""
|
|
3
|
+
Discrete Gaussian Samplers over Lattices
|
|
4
|
+
|
|
5
|
+
This file implements oracles which return samples from a lattice following a
|
|
6
|
+
discrete Gaussian distribution. That is, if `\sigma` is big enough relative to
|
|
7
|
+
the provided basis, then vectors are returned with a probability proportional
|
|
8
|
+
to `\exp(-|x - c|_2^2 / (2\sigma^2))`. More precisely lattice vectors in `x \in
|
|
9
|
+
\Lambda` are returned with probability:
|
|
10
|
+
|
|
11
|
+
.. MATH::
|
|
12
|
+
|
|
13
|
+
\frac{\exp(-|x - c|_2^2 / (2\sigma^2))}{\sum_{v \in \Lambda} \exp(-|v|_2^2 /
|
|
14
|
+
(2\sigma^2))}.
|
|
15
|
+
|
|
16
|
+
AUTHORS:
|
|
17
|
+
|
|
18
|
+
- Martin Albrecht (2014-06-28): initial version
|
|
19
|
+
|
|
20
|
+
- Gareth Ma (2023-09-22): implement non-spherical sampling
|
|
21
|
+
|
|
22
|
+
EXAMPLES::
|
|
23
|
+
|
|
24
|
+
sage: D = distributions.DiscreteGaussianDistributionLatticeSampler(ZZ^10, 3.0)
|
|
25
|
+
sage: D(), D(), D() # random
|
|
26
|
+
((3, 0, -5, 0, -1, -3, 3, 3, -7, 2), (4, 0, 1, -2, -4, -4, 4, 0, 1, -4), (-3, 0, 4, 5, 0, 1, 3, 2, 0, -1))
|
|
27
|
+
sage: a = D()
|
|
28
|
+
sage: a.parent()
|
|
29
|
+
Ambient free module of rank 10 over the principal ideal domain Integer Ring
|
|
30
|
+
"""
|
|
31
|
+
# ******************************************************************************
|
|
32
|
+
#
|
|
33
|
+
# DGS - Discrete Gaussian Samplers
|
|
34
|
+
#
|
|
35
|
+
# Copyright (c) 2014, Martin Albrecht <martinralbrecht+dgs@googlemail.com>
|
|
36
|
+
# All rights reserved.
|
|
37
|
+
#
|
|
38
|
+
# Redistribution and use in source and binary forms, with or without
|
|
39
|
+
# modification, are permitted provided that the following conditions are met:
|
|
40
|
+
#
|
|
41
|
+
# 1. Redistributions of source code must retain the above copyright notice, this
|
|
42
|
+
# list of conditions and the following disclaimer.
|
|
43
|
+
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
|
44
|
+
# this list of conditions and the following disclaimer in the documentation
|
|
45
|
+
# and/or other materials provided with the distribution.
|
|
46
|
+
#
|
|
47
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
48
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
49
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
50
|
+
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
|
51
|
+
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
52
|
+
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
53
|
+
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
54
|
+
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
55
|
+
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
56
|
+
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
57
|
+
#
|
|
58
|
+
# The views and conclusions contained in the software and documentation are
|
|
59
|
+
# those of the authors and should not be interpreted as representing official
|
|
60
|
+
# policies, either expressed or implied, of the FreeBSD Project.
|
|
61
|
+
# *****************************************************************************/
|
|
62
|
+
|
|
63
|
+
from sage.functions.log import exp
|
|
64
|
+
from sage.rings.real_mpfr import RealField
|
|
65
|
+
from sage.rings.integer_ring import ZZ
|
|
66
|
+
from sage.rings.rational_field import QQ
|
|
67
|
+
from sage.stats.distributions.discrete_gaussian_integer import DiscreteGaussianDistributionIntegerSampler
|
|
68
|
+
from sage.structure.sage_object import SageObject
|
|
69
|
+
from sage.misc.cachefunc import cached_method
|
|
70
|
+
from sage.misc.functional import sqrt
|
|
71
|
+
from sage.misc.lazy_import import lazy_import
|
|
72
|
+
from sage.misc.prandom import normalvariate
|
|
73
|
+
from sage.misc.verbose import verbose
|
|
74
|
+
from sage.matrix.constructor import matrix
|
|
75
|
+
from sage.modules.free_module import FreeModule
|
|
76
|
+
from sage.modules.free_module_element import vector
|
|
77
|
+
|
|
78
|
+
lazy_import('sage.symbolic.constants', 'pi')
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def _iter_vectors(n, lower, upper, step=None):
|
|
82
|
+
r"""
|
|
83
|
+
Iterate over all integer vectors of length ``n`` between ``lower`` and
|
|
84
|
+
``upper`` bound.
|
|
85
|
+
|
|
86
|
+
INPUT:
|
|
87
|
+
|
|
88
|
+
- ``n`` -- integer ``>0``; length
|
|
89
|
+
- ``lower`` -- integer ``< upper``; lower bound (inclusive)
|
|
90
|
+
- ``upper`` -- integer ``> lower``; upper bound (exclusive)
|
|
91
|
+
- ``step`` -- used for recursion, ignore
|
|
92
|
+
|
|
93
|
+
EXAMPLES::
|
|
94
|
+
|
|
95
|
+
sage: from sage.stats.distributions.discrete_gaussian_lattice import _iter_vectors
|
|
96
|
+
sage: list(_iter_vectors(2, -1, 2))
|
|
97
|
+
[(-1, -1), (0, -1), (1, -1), (-1, 0), (0, 0), (1, 0), (-1, 1), (0, 1), (1, 1)]
|
|
98
|
+
"""
|
|
99
|
+
if step is None:
|
|
100
|
+
if ZZ(lower) >= ZZ(upper):
|
|
101
|
+
raise ValueError("expected lower < upper, but got %d >= %d" % (lower, upper))
|
|
102
|
+
if ZZ(n) <= 0:
|
|
103
|
+
raise ValueError("expected n>0 but got %d <= 0" % n)
|
|
104
|
+
step = n
|
|
105
|
+
|
|
106
|
+
assert step > 0
|
|
107
|
+
if step == 1:
|
|
108
|
+
for x in range(lower, upper):
|
|
109
|
+
v = vector(ZZ, n)
|
|
110
|
+
v[0] = x
|
|
111
|
+
yield v
|
|
112
|
+
return
|
|
113
|
+
else:
|
|
114
|
+
for x in range(lower, upper):
|
|
115
|
+
for v in _iter_vectors(n, lower, upper, step - 1):
|
|
116
|
+
v[step - 1] = x
|
|
117
|
+
yield v
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
class DiscreteGaussianDistributionLatticeSampler(SageObject):
|
|
121
|
+
r"""
|
|
122
|
+
GPV sampler for Discrete Gaussians over Lattices.
|
|
123
|
+
|
|
124
|
+
EXAMPLES::
|
|
125
|
+
|
|
126
|
+
sage: D = distributions.DiscreteGaussianDistributionLatticeSampler(ZZ^10, 3.0); D
|
|
127
|
+
Discrete Gaussian sampler with Gaussian parameter σ = 3.00000000000000, c=(0, 0, 0, 0, 0, 0, 0, 0, 0, 0) over lattice with basis
|
|
128
|
+
<BLANKLINE>
|
|
129
|
+
[1 0 0 0 0 0 0 0 0 0]
|
|
130
|
+
[0 1 0 0 0 0 0 0 0 0]
|
|
131
|
+
[0 0 1 0 0 0 0 0 0 0]
|
|
132
|
+
[0 0 0 1 0 0 0 0 0 0]
|
|
133
|
+
[0 0 0 0 1 0 0 0 0 0]
|
|
134
|
+
[0 0 0 0 0 1 0 0 0 0]
|
|
135
|
+
[0 0 0 0 0 0 1 0 0 0]
|
|
136
|
+
[0 0 0 0 0 0 0 1 0 0]
|
|
137
|
+
[0 0 0 0 0 0 0 0 1 0]
|
|
138
|
+
[0 0 0 0 0 0 0 0 0 1]
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
We plot a histogram::
|
|
142
|
+
|
|
143
|
+
sage: import warnings
|
|
144
|
+
sage: warnings.simplefilter('ignore', UserWarning)
|
|
145
|
+
sage: D = distributions.DiscreteGaussianDistributionLatticeSampler(identity_matrix(2), 3.0)
|
|
146
|
+
sage: S = [D() for _ in range(2^12)]
|
|
147
|
+
sage: l = [vector(v.list() + [S.count(v)]) for v in set(S)]
|
|
148
|
+
sage: list_plot3d(l, point_list=True, interpolation='nn') # needs sage.plot
|
|
149
|
+
Graphics3d Object
|
|
150
|
+
|
|
151
|
+
REFERENCES:
|
|
152
|
+
|
|
153
|
+
- [GPV2008]_
|
|
154
|
+
|
|
155
|
+
.. automethod:: __init__
|
|
156
|
+
.. automethod:: __call__
|
|
157
|
+
"""
|
|
158
|
+
@staticmethod
|
|
159
|
+
def compute_precision(precision, sigma):
|
|
160
|
+
r"""
|
|
161
|
+
Compute precision to use.
|
|
162
|
+
|
|
163
|
+
INPUT:
|
|
164
|
+
|
|
165
|
+
- ``precision`` -- integer `>= 53` nor ``None``
|
|
166
|
+
- ``sigma`` -- if ``precision`` is ``None`` then the precision of
|
|
167
|
+
``sigma`` is used
|
|
168
|
+
|
|
169
|
+
EXAMPLES::
|
|
170
|
+
|
|
171
|
+
sage: DGL = distributions.DiscreteGaussianDistributionLatticeSampler
|
|
172
|
+
sage: DGL.compute_precision(100, RR(3))
|
|
173
|
+
100
|
|
174
|
+
sage: DGL.compute_precision(100, RealField(200)(3))
|
|
175
|
+
100
|
|
176
|
+
sage: DGL.compute_precision(100, 3)
|
|
177
|
+
100
|
|
178
|
+
sage: DGL.compute_precision(None, RR(3))
|
|
179
|
+
53
|
|
180
|
+
sage: DGL.compute_precision(None, RealField(200)(3))
|
|
181
|
+
200
|
|
182
|
+
sage: DGL.compute_precision(None, 3)
|
|
183
|
+
53
|
|
184
|
+
"""
|
|
185
|
+
if precision is None:
|
|
186
|
+
try:
|
|
187
|
+
precision = ZZ(sigma.precision())
|
|
188
|
+
except AttributeError:
|
|
189
|
+
return 53
|
|
190
|
+
precision = max(53, precision)
|
|
191
|
+
return precision
|
|
192
|
+
|
|
193
|
+
def _normalisation_factor_zz(self, tau=None, prec=None):
|
|
194
|
+
r"""
|
|
195
|
+
This function returns an approximation of `\sum_{x \in B}
|
|
196
|
+
\exp(-|x|_2^2 / (2\sigma^2))`, i.e. the normalization factor such that the sum
|
|
197
|
+
over all probabilities is 1 for `B`, via Poisson summation.
|
|
198
|
+
|
|
199
|
+
INPUT:
|
|
200
|
+
|
|
201
|
+
- ``tau`` -- (default: ``None``) all vectors `v` with `|v|_2^2 \leq
|
|
202
|
+
\tau \sigma` are enumerated; if none is provided, enumerate vectors
|
|
203
|
+
with increasing norm until the sum converges to given precision. For
|
|
204
|
+
high dimension lattice, this is recommended.
|
|
205
|
+
|
|
206
|
+
- ``prec`` -- (default: ``None``) passed to :meth:`compute_precision`
|
|
207
|
+
|
|
208
|
+
EXAMPLES::
|
|
209
|
+
|
|
210
|
+
sage: # needs sage.libs.pari
|
|
211
|
+
sage: n = 3; sigma = 1.0
|
|
212
|
+
sage: D = distributions.DiscreteGaussianDistributionLatticeSampler(ZZ^n, sigma)
|
|
213
|
+
sage: f = D.f
|
|
214
|
+
sage: nf = D._normalisation_factor_zz(); nf
|
|
215
|
+
15.7496...
|
|
216
|
+
sage: from collections import defaultdict
|
|
217
|
+
sage: counter = defaultdict(Integer)
|
|
218
|
+
sage: m = 0
|
|
219
|
+
sage: def add_samples(i):
|
|
220
|
+
....: global counter, m
|
|
221
|
+
....: for _ in range(i):
|
|
222
|
+
....: counter[D()] += 1
|
|
223
|
+
....: m += 1
|
|
224
|
+
sage: v = vector(ZZ, n, (0, 0, 0))
|
|
225
|
+
sage: v.set_immutable()
|
|
226
|
+
sage: while v not in counter:
|
|
227
|
+
....: add_samples(1000)
|
|
228
|
+
sage: while abs(m*f(v)*1.0/nf/counter[v] - 1.0) >= 0.1:
|
|
229
|
+
....: add_samples(1000)
|
|
230
|
+
sage: v = vector(ZZ, n, (-1, 2, 3))
|
|
231
|
+
sage: v.set_immutable()
|
|
232
|
+
sage: while v not in counter:
|
|
233
|
+
....: add_samples(1000)
|
|
234
|
+
sage: while abs(m*f(v)*1.0/nf/counter[v] - 1.0) >= 0.2: # long time
|
|
235
|
+
....: add_samples(1000)
|
|
236
|
+
sage: DGL = distributions.DiscreteGaussianDistributionLatticeSampler
|
|
237
|
+
sage: D = DGL(ZZ^8, 0.5)
|
|
238
|
+
sage: D._normalisation_factor_zz(tau=3)
|
|
239
|
+
3.1653...
|
|
240
|
+
sage: D._normalisation_factor_zz()
|
|
241
|
+
6.8249...
|
|
242
|
+
sage: D = DGL(ZZ^8, 1000)
|
|
243
|
+
sage: round(D._normalisation_factor_zz(prec=100)) # needs sage.symbolic
|
|
244
|
+
1558545456544038969634991553
|
|
245
|
+
sage: M = Matrix(ZZ, [[1, 3, 0], [-2, 5, 1], [3, -4, 2]])
|
|
246
|
+
sage: D = DGL(M, 1.7)
|
|
247
|
+
sage: D._normalisation_factor_zz() # long time
|
|
248
|
+
Traceback (most recent call last):
|
|
249
|
+
...
|
|
250
|
+
NotImplementedError: center must be at zero and basis must be trivial
|
|
251
|
+
sage: Sigma = Matrix(ZZ, [[5, -2, 4], [-2, 10, -5], [4, -5, 5]])
|
|
252
|
+
sage: D = DGL(ZZ^3, Sigma, [7, 2, 5])
|
|
253
|
+
sage: D._normalisation_factor_zz() # needs fpylll
|
|
254
|
+
78.6804...
|
|
255
|
+
sage: M = Matrix(ZZ, [[1, 3, 0], [-2, 5, 1]])
|
|
256
|
+
sage: D = DGL(M, 3)
|
|
257
|
+
sage: D._normalisation_factor_zz()
|
|
258
|
+
Traceback (most recent call last):
|
|
259
|
+
...
|
|
260
|
+
NotImplementedError: basis must be a square matrix
|
|
261
|
+
sage: D = DGL(ZZ^3, c=(1/2, 0, 0))
|
|
262
|
+
sage: D._normalisation_factor_zz()
|
|
263
|
+
Traceback (most recent call last):
|
|
264
|
+
...
|
|
265
|
+
NotImplementedError: center must be at zero and basis must be trivial
|
|
266
|
+
sage: D = DGL(Matrix(3, 3, 1/2))
|
|
267
|
+
sage: D._normalisation_factor_zz()
|
|
268
|
+
Traceback (most recent call last):
|
|
269
|
+
...
|
|
270
|
+
NotImplementedError: lattice must be integral
|
|
271
|
+
"""
|
|
272
|
+
# If σ > 1:
|
|
273
|
+
# We use the Fourier transform g(t) of f(x) = exp(-k^2 / 2σ^2), but
|
|
274
|
+
# taking the norm of vector t^2 as input, and with norm_factor factored.
|
|
275
|
+
# If σ ≤ 1:
|
|
276
|
+
# The formula in docstring converges quickly since it has -1 / σ^2 in
|
|
277
|
+
# the exponent
|
|
278
|
+
def f_or_hat(x):
|
|
279
|
+
# Fun fact: If you remove this R() and delay the call to return,
|
|
280
|
+
# It might give an error due to precision error. For example,
|
|
281
|
+
# RR(1 + 100 * exp(-5.0 * pi^2)) == 0
|
|
282
|
+
|
|
283
|
+
if sigma > 1:
|
|
284
|
+
return R(exp(-pi**2 * (2 * sigma**2) * x))
|
|
285
|
+
|
|
286
|
+
return R(exp(-x / (2 * sigma**2)))
|
|
287
|
+
|
|
288
|
+
if not self.is_spherical:
|
|
289
|
+
# TODO: This is only a poor approximation placeholder.
|
|
290
|
+
# It should be easy to implement, since the Fourier transform
|
|
291
|
+
# is essentially the same, but I can't figure out how to
|
|
292
|
+
# tweak the `.qfrep` call below correctly.
|
|
293
|
+
from warnings import warn
|
|
294
|
+
warn("Note: `_normalisation_factor_zz` has not been properly "
|
|
295
|
+
"implemented for non-spherical distributions.")
|
|
296
|
+
import itertools
|
|
297
|
+
from sage.functions.log import log
|
|
298
|
+
basis = self.B.LLL()
|
|
299
|
+
base = vector(ZZ, [v.round() for v in basis.solve_left(self._c)])
|
|
300
|
+
# BOUND is the largest integer such that |coords| <= 10^4
|
|
301
|
+
# However, this might still drift from true value for larger lattices
|
|
302
|
+
# So optimally one should fix the TODO above
|
|
303
|
+
BOUND = max(1, (self._RR(10**(4 / self.n)).ceil() - 1) // 2)
|
|
304
|
+
BOUND = min(BOUND, 10)
|
|
305
|
+
coords = itertools.product(range(-BOUND, BOUND + 1), repeat=self.n)
|
|
306
|
+
return sum(self.f((vector(u) + base) * self.B) for u in coords)
|
|
307
|
+
|
|
308
|
+
if self.B.nrows() != self.B.ncols():
|
|
309
|
+
raise NotImplementedError("basis must be a square matrix")
|
|
310
|
+
|
|
311
|
+
if self.B.base_ring() != ZZ:
|
|
312
|
+
raise NotImplementedError("lattice must be integral")
|
|
313
|
+
|
|
314
|
+
if self.is_spherical and not self._c_in_lattice_and_lattice_trivial:
|
|
315
|
+
raise NotImplementedError("center must be at zero and basis must be trivial")
|
|
316
|
+
|
|
317
|
+
sigma = self._sigma
|
|
318
|
+
prec = DiscreteGaussianDistributionLatticeSampler.compute_precision(
|
|
319
|
+
prec, sigma
|
|
320
|
+
)
|
|
321
|
+
R = RealField(prec=prec)
|
|
322
|
+
if sigma > 1:
|
|
323
|
+
det = self.B.det()
|
|
324
|
+
norm_factor = (sigma * sqrt(2 * pi))**self.n / det
|
|
325
|
+
else:
|
|
326
|
+
det = 1
|
|
327
|
+
norm_factor = 1
|
|
328
|
+
|
|
329
|
+
# qfrep computes theta series of a quadratic form, which is *half* the
|
|
330
|
+
# generating function of number of vectors with given norm (and no 0)
|
|
331
|
+
Q = self.Q
|
|
332
|
+
if tau is not None:
|
|
333
|
+
freq = Q.__pari__().qfrep(tau * sigma, 0)
|
|
334
|
+
res = R(1)
|
|
335
|
+
for x, fq in enumerate(freq):
|
|
336
|
+
res += 2 * ZZ(fq) * f_or_hat((x + 1) / det**self.n)
|
|
337
|
+
return R(norm_factor * res)
|
|
338
|
+
|
|
339
|
+
res = R(1)
|
|
340
|
+
bound = 0
|
|
341
|
+
# There might still be precision issue but whatever
|
|
342
|
+
while True:
|
|
343
|
+
bound += 1
|
|
344
|
+
cnt = ZZ(Q.__pari__().qfrep(bound, 0)[bound - 1])
|
|
345
|
+
inc = 2 * cnt * f_or_hat(bound / det**self.n)
|
|
346
|
+
if cnt > 0 and res == res + inc:
|
|
347
|
+
return R(norm_factor * res)
|
|
348
|
+
res += inc
|
|
349
|
+
|
|
350
|
+
@cached_method
|
|
351
|
+
def _maximal_r(self):
|
|
352
|
+
r"""
|
|
353
|
+
This function computes the largest value `r > 0` such that `\Sigma - r^2BB^T`
|
|
354
|
+
is positive definite.
|
|
355
|
+
|
|
356
|
+
This is equivalent to finding `\lambda_1(\Sigma / Q) = 1 / \lambda_n(Q
|
|
357
|
+
/ \Sigma)`, which is done via the Power iteration method.
|
|
358
|
+
|
|
359
|
+
EXAMPLES::
|
|
360
|
+
|
|
361
|
+
sage: n = 3
|
|
362
|
+
sage: Sigma = Matrix(ZZ, [[5, -2, 4], [-2, 10, -5], [4, -5, 5]])
|
|
363
|
+
sage: c = vector(ZZ, [7, 2, 5])
|
|
364
|
+
sage: D = distributions.DiscreteGaussianDistributionLatticeSampler(ZZ^n, Sigma, c)
|
|
365
|
+
sage: r = D._maximal_r(); r
|
|
366
|
+
0.58402...
|
|
367
|
+
sage: e_vals = (D.sigma() - r^2 * D.Q).eigenvalues() # needs sage.libs.pari
|
|
368
|
+
sage: assert all(e_val >= -1e-12 for e_val in e_vals) # needs sage.libs.pari
|
|
369
|
+
"""
|
|
370
|
+
assert not self.is_spherical
|
|
371
|
+
|
|
372
|
+
Q = self.Q.change_ring(self._RR) / self._sigma.change_ring(self._RR)
|
|
373
|
+
v = Q[0].change_ring(self._RR)
|
|
374
|
+
cnt = 0
|
|
375
|
+
while cnt < 10000:
|
|
376
|
+
nv = (Q * v).normalized()
|
|
377
|
+
if (nv - v).norm() < 1e-12:
|
|
378
|
+
break
|
|
379
|
+
v = nv
|
|
380
|
+
cnt += 1
|
|
381
|
+
res = (v[0] / (Q * v)[0]).sqrt()
|
|
382
|
+
return res
|
|
383
|
+
|
|
384
|
+
def _randomise(self, v):
|
|
385
|
+
r"""
|
|
386
|
+
Randomly round to the latice coset `\ZZ + v` with Gaussian parameter
|
|
387
|
+
`r`. Used at :meth:`_call_non_spherical`.
|
|
388
|
+
|
|
389
|
+
REFERENCES:
|
|
390
|
+
|
|
391
|
+
- [Pei2010]_, Section 4.1
|
|
392
|
+
|
|
393
|
+
EXAMPLES::
|
|
394
|
+
|
|
395
|
+
sage: Sigma = Matrix(ZZ, [[5, -2, 4], [-2, 10, -5], [4, -5, 5]])
|
|
396
|
+
sage: D = distributions.DiscreteGaussianDistributionLatticeSampler(ZZ^3, Sigma)
|
|
397
|
+
sage: all(D._randomise([0, 0, 0]).norm() <= 16 for _ in range(100)) # needs sage.symbolic
|
|
398
|
+
True
|
|
399
|
+
"""
|
|
400
|
+
return vector(ZZ, [DiscreteGaussianDistributionIntegerSampler(self.r, c=vi)() for vi in v])
|
|
401
|
+
|
|
402
|
+
def __init__(self, B, sigma=1, c=0, r=None, precision=None, sigma_basis=False):
|
|
403
|
+
r"""
|
|
404
|
+
Construct a discrete Gaussian sampler over the lattice `\Lambda(B)`
|
|
405
|
+
with parameter ``sigma`` and center `c`.
|
|
406
|
+
|
|
407
|
+
INPUT:
|
|
408
|
+
|
|
409
|
+
- ``B`` -- a (row) basis for the lattice, one of the following:
|
|
410
|
+
|
|
411
|
+
- an integer matrix,
|
|
412
|
+
- an object with a ``.matrix()`` method, e.g. ``ZZ^n``, or
|
|
413
|
+
- an object where ``matrix(B)`` succeeds, e.g. a list of vectors
|
|
414
|
+
|
|
415
|
+
- ``sigma`` -- Gaussian parameter, one of the following:
|
|
416
|
+
|
|
417
|
+
- a real number `\sigma > 0` (spherical),
|
|
418
|
+
- a positive definite matrix `\Sigma` (non-spherical), or
|
|
419
|
+
- any matrix-like ``S``, equivalent to `\Sigma = SS^T`, when
|
|
420
|
+
``sigma_basis`` is set
|
|
421
|
+
|
|
422
|
+
- ``c`` -- (default: 0) center `c`, any vector in `\ZZ^n` is
|
|
423
|
+
supported, but `c \in \Lambda(B)` is faster
|
|
424
|
+
|
|
425
|
+
- ``r`` -- (default: ``None``) rounding parameter `r` as defined in
|
|
426
|
+
[Pei2010]_; ignored for spherical Gaussian parameter; if not provided,
|
|
427
|
+
set to be the maximal possible such that `\Sigma - rBB^T` is positive
|
|
428
|
+
definite
|
|
429
|
+
- ``precision`` -- bit precision `\geq 53`
|
|
430
|
+
- ``sigma_basis`` -- boolean (default: ``False``); when set, ``sigma`` is treated as
|
|
431
|
+
a (row) basis, i.e. the covariance matrix is computed by `\Sigma = SS^T`
|
|
432
|
+
|
|
433
|
+
.. TODO::
|
|
434
|
+
|
|
435
|
+
Rename class methods like ``.f`` and hide most of them
|
|
436
|
+
(at least behind something like ``.data``).
|
|
437
|
+
|
|
438
|
+
EXAMPLES::
|
|
439
|
+
|
|
440
|
+
sage: n = 2; sigma = 3.0
|
|
441
|
+
sage: D = distributions.DiscreteGaussianDistributionLatticeSampler(ZZ^n, sigma)
|
|
442
|
+
sage: f = D.f
|
|
443
|
+
sage: nf = D._normalisation_factor_zz(); nf # needs sage.symbolic
|
|
444
|
+
56.5486677646...
|
|
445
|
+
|
|
446
|
+
sage: from collections import defaultdict
|
|
447
|
+
sage: counter = defaultdict(Integer); m = 0
|
|
448
|
+
sage: def add_samples(i):
|
|
449
|
+
....: global counter, m
|
|
450
|
+
....: for _ in range(i):
|
|
451
|
+
....: counter[D()] += 1
|
|
452
|
+
....: m += 1
|
|
453
|
+
|
|
454
|
+
sage: v = vector(ZZ, n, (-3, -3))
|
|
455
|
+
sage: v.set_immutable()
|
|
456
|
+
sage: while v not in counter: add_samples(1000)
|
|
457
|
+
sage: while abs(m*f(v)*1.0/nf/counter[v] - 1.0) >= 0.1: # needs sage.symbolic
|
|
458
|
+
....: add_samples(1000)
|
|
459
|
+
|
|
460
|
+
sage: counter = defaultdict(Integer); m = 0
|
|
461
|
+
sage: v = vector(ZZ, n, (0, 0))
|
|
462
|
+
sage: v.set_immutable()
|
|
463
|
+
sage: while v not in counter:
|
|
464
|
+
....: add_samples(1000)
|
|
465
|
+
sage: while abs(m*f(v)*1.0/nf/counter[v] - 1.0) >= 0.1: # needs sage.symbolic
|
|
466
|
+
....: add_samples(1000)
|
|
467
|
+
|
|
468
|
+
Spherical covariance are automatically handled::
|
|
469
|
+
|
|
470
|
+
sage: distributions.DiscreteGaussianDistributionLatticeSampler(ZZ^3, sigma=Matrix(3, 3, 2))
|
|
471
|
+
Discrete Gaussian sampler with Gaussian parameter σ = 2.00000000000000, c=(0, 0, 0) over lattice with basis
|
|
472
|
+
<BLANKLINE>
|
|
473
|
+
[1 0 0]
|
|
474
|
+
[0 1 0]
|
|
475
|
+
[0 0 1]
|
|
476
|
+
|
|
477
|
+
The sampler supports non-spherical covariance in the form of a Gram
|
|
478
|
+
matrix::
|
|
479
|
+
|
|
480
|
+
sage: n = 3
|
|
481
|
+
sage: Sigma = Matrix(ZZ, [[5, -2, 4], [-2, 10, -5], [4, -5, 5]])
|
|
482
|
+
sage: c = vector(ZZ, [7, 2, 5])
|
|
483
|
+
sage: D = distributions.DiscreteGaussianDistributionLatticeSampler(ZZ^n, Sigma, c)
|
|
484
|
+
sage: f = D.f
|
|
485
|
+
sage: nf = D._normalisation_factor_zz(); nf # This has not been properly implemented # needs fpylll
|
|
486
|
+
78.6804...
|
|
487
|
+
|
|
488
|
+
We can compute the expected number of samples before sampling a vector::
|
|
489
|
+
|
|
490
|
+
sage: v = vector(ZZ, n, (11, 4, 8))
|
|
491
|
+
sage: v.set_immutable()
|
|
492
|
+
sage: 1 / (f(v) / nf) # needs fpylll
|
|
493
|
+
2553.9461...
|
|
494
|
+
|
|
495
|
+
sage: counter = defaultdict(Integer); m = 0
|
|
496
|
+
sage: while v not in counter:
|
|
497
|
+
....: add_samples(1000)
|
|
498
|
+
sage: sum(counter.values()) # random
|
|
499
|
+
3000
|
|
500
|
+
sage: while abs(m*f(v)*1.0/nf/counter[v] - 1.0) >= 0.1: # needs fpylll sage.symbolic
|
|
501
|
+
....: add_samples(1000)
|
|
502
|
+
|
|
503
|
+
If the covariance provided is not positive definite, an error is thrown::
|
|
504
|
+
|
|
505
|
+
sage: Sigma = Matrix(ZZ, [[0, 1], [1, 0]])
|
|
506
|
+
sage: distributions.DiscreteGaussianDistributionLatticeSampler(ZZ^2, Sigma)
|
|
507
|
+
Traceback (most recent call last):
|
|
508
|
+
...
|
|
509
|
+
RuntimeError: Sigma(=[0.000000000000000 1.00000000000000]
|
|
510
|
+
[ 1.00000000000000 0.000000000000000]) is not positive definite
|
|
511
|
+
|
|
512
|
+
The sampler supports passing a basis for the covariance::
|
|
513
|
+
|
|
514
|
+
sage: n = 3
|
|
515
|
+
sage: S = Matrix(ZZ, [[2, 0, 0], [-1, 3, 0], [2, -1, 1]])
|
|
516
|
+
sage: D = distributions.DiscreteGaussianDistributionLatticeSampler(ZZ^n, S, sigma_basis=True)
|
|
517
|
+
sage: D.sigma()
|
|
518
|
+
[ 4.00000000000000 -2.00000000000000 4.00000000000000]
|
|
519
|
+
[-2.00000000000000 10.0000000000000 -5.00000000000000]
|
|
520
|
+
[ 4.00000000000000 -5.00000000000000 6.00000000000000]
|
|
521
|
+
|
|
522
|
+
The non-spherical sampler supports offline computation to speed up
|
|
523
|
+
sampling. This will be useful when changing the center `c` is supported.
|
|
524
|
+
The difference is more significant for larger matrices. For 128x128 we
|
|
525
|
+
observe a 4x speedup (86s -> 20s)::
|
|
526
|
+
|
|
527
|
+
sage: D.offline_samples = []
|
|
528
|
+
sage: T = 2**12
|
|
529
|
+
sage: L = [D() for _ in range(T)] # 560ms
|
|
530
|
+
sage: D.add_offline_samples(T) # 150ms
|
|
531
|
+
sage: L = [D() for _ in range(T)] # 370ms
|
|
532
|
+
|
|
533
|
+
We can also initialise with matrix-like objects::
|
|
534
|
+
|
|
535
|
+
sage: qf = matrix(3, [2, 1, 1, 1, 2, 1, 1, 1, 2])
|
|
536
|
+
sage: D = distributions.DiscreteGaussianDistributionLatticeSampler(qf, 3.0); D
|
|
537
|
+
Discrete Gaussian sampler with Gaussian parameter σ = 3.00000000000000, c=(0, 0, 0) over lattice with basis
|
|
538
|
+
<BLANKLINE>
|
|
539
|
+
[2 1 1]
|
|
540
|
+
[1 2 1]
|
|
541
|
+
[1 1 2]
|
|
542
|
+
sage: D().parent() is D.c().parent() # needs sage.symbolic
|
|
543
|
+
True
|
|
544
|
+
"""
|
|
545
|
+
precision = DiscreteGaussianDistributionLatticeSampler.compute_precision(precision, sigma)
|
|
546
|
+
|
|
547
|
+
self._RR = RealField(precision)
|
|
548
|
+
# Check if sigma is a (real) number or a scaled identity matrix
|
|
549
|
+
self.is_spherical = True
|
|
550
|
+
try:
|
|
551
|
+
self._sigma = self._RR(sigma)
|
|
552
|
+
except TypeError:
|
|
553
|
+
self._sigma = matrix(self._RR, sigma)
|
|
554
|
+
# Will it be "annoying" if a matrix Sigma has different behaviour
|
|
555
|
+
# sometimes? There should be a parameter in the constructor
|
|
556
|
+
if self._sigma == self._sigma[0, 0]:
|
|
557
|
+
self._sigma = self._RR(self._sigma[0, 0])
|
|
558
|
+
else:
|
|
559
|
+
if sigma_basis:
|
|
560
|
+
self._sigma = self._sigma * self._sigma.T
|
|
561
|
+
if not self._sigma.is_positive_definite():
|
|
562
|
+
raise RuntimeError(f"Sigma(={self._sigma}) is not positive definite")
|
|
563
|
+
self.is_spherical = False
|
|
564
|
+
|
|
565
|
+
# TODO: Support taking a basis for the covariance
|
|
566
|
+
try:
|
|
567
|
+
B = matrix(B)
|
|
568
|
+
except (TypeError, ValueError):
|
|
569
|
+
pass
|
|
570
|
+
|
|
571
|
+
try:
|
|
572
|
+
B = B.matrix()
|
|
573
|
+
except AttributeError:
|
|
574
|
+
pass
|
|
575
|
+
|
|
576
|
+
self.n = B.ncols()
|
|
577
|
+
self.B = B
|
|
578
|
+
self.Q = B * B.T
|
|
579
|
+
self._G = B.gram_schmidt()[0]
|
|
580
|
+
self._c_in_lattice_and_lattice_trivial = False
|
|
581
|
+
|
|
582
|
+
self.D = None
|
|
583
|
+
self.VS = None
|
|
584
|
+
self._c_mul_B_inv = None
|
|
585
|
+
self.r = r
|
|
586
|
+
|
|
587
|
+
self.set_c(c)
|
|
588
|
+
|
|
589
|
+
def _precompute_data(self):
|
|
590
|
+
r"""
|
|
591
|
+
Precompute basis data. Do not call this method directly.
|
|
592
|
+
|
|
593
|
+
EXAMPLES::
|
|
594
|
+
|
|
595
|
+
sage: D = distributions.DiscreteGaussianDistributionLatticeSampler(ZZ^3, 3.0, c=(1,0,0))
|
|
596
|
+
sage: D.set_c((2, 0, 0))
|
|
597
|
+
sage: D
|
|
598
|
+
Discrete Gaussian sampler with Gaussian parameter σ = 3.00000000000000, c=(2, 0, 0) over lattice with basis
|
|
599
|
+
<BLANKLINE>
|
|
600
|
+
[1 0 0]
|
|
601
|
+
[0 1 0]
|
|
602
|
+
[0 0 1]
|
|
603
|
+
|
|
604
|
+
.. NOTE::
|
|
605
|
+
|
|
606
|
+
Do not call this method directly, it is called automatically from
|
|
607
|
+
:func:`DiscreteGaussianDistributionLatticeSampler.__init__`.
|
|
608
|
+
"""
|
|
609
|
+
|
|
610
|
+
if self.is_spherical:
|
|
611
|
+
# deal with trivial case first, it is common
|
|
612
|
+
if self._c == 0 and self._G == 1:
|
|
613
|
+
self._c_in_lattice_and_lattice_trivial = True
|
|
614
|
+
D = DiscreteGaussianDistributionIntegerSampler(sigma=self._sigma)
|
|
615
|
+
self.D = tuple([D for _ in range(self.B.nrows())])
|
|
616
|
+
self.VS = FreeModule(ZZ, self.B.nrows())
|
|
617
|
+
|
|
618
|
+
else:
|
|
619
|
+
w = self.B.solve_left(self._c)
|
|
620
|
+
if w in ZZ ** self.B.nrows() and self._G == 1:
|
|
621
|
+
self._c_in_lattice_and_lattice_trivial = True
|
|
622
|
+
D = []
|
|
623
|
+
for i in range(self.B.nrows()):
|
|
624
|
+
sigma_ = self._sigma / self._G[i].norm()
|
|
625
|
+
D.append(DiscreteGaussianDistributionIntegerSampler(sigma=sigma_))
|
|
626
|
+
self.D = tuple(D)
|
|
627
|
+
self.VS = FreeModule(ZZ, self.B.nrows())
|
|
628
|
+
else:
|
|
629
|
+
# Variables Sigma2 and r are from [Pei2010]_
|
|
630
|
+
# TODO: B is implicitly assumed to be full-rank for the
|
|
631
|
+
# non-spherical case. Remove this assumption :)
|
|
632
|
+
|
|
633
|
+
# Offline samples of B⁻¹D₁
|
|
634
|
+
self.offline_samples = []
|
|
635
|
+
self.B_inv = self.B.inverse()
|
|
636
|
+
self.sigma_inv = self._sigma.inverse()
|
|
637
|
+
self._c_mul_B_inv = self._c * self.B_inv
|
|
638
|
+
|
|
639
|
+
if self.r is None:
|
|
640
|
+
# Compute the maximal r such that (Sigma - r^2 * Q) > 0
|
|
641
|
+
self.r = self._maximal_r() * 0.9999
|
|
642
|
+
self.r = self._RR(self.r)
|
|
643
|
+
|
|
644
|
+
Sigma2 = self._sigma - self.r**2 * self.Q
|
|
645
|
+
try:
|
|
646
|
+
verbose(f"Computing Cholesky decomposition of a {Sigma2.dimensions()} matrix")
|
|
647
|
+
self.B2 = Sigma2.cholesky().T
|
|
648
|
+
self.B2_B_inv = self.B2 * self.B_inv
|
|
649
|
+
except ValueError:
|
|
650
|
+
raise ValueError("Σ₂ is not positive definite. Is your "
|
|
651
|
+
f"r(={self.r}) too large? It should be at most "
|
|
652
|
+
f"{self._maximal_r()}")
|
|
653
|
+
|
|
654
|
+
def __call__(self):
|
|
655
|
+
r"""
|
|
656
|
+
Return a new sample.
|
|
657
|
+
|
|
658
|
+
EXAMPLES::
|
|
659
|
+
|
|
660
|
+
sage: D = distributions.DiscreteGaussianDistributionLatticeSampler(ZZ^3, 3.0, c=(1,0,0))
|
|
661
|
+
sage: L = [D() for _ in range(2^12)]
|
|
662
|
+
sage: mean_L = sum(L) / len(L)
|
|
663
|
+
sage: norm(mean_L.n() - D.c()) < 0.25
|
|
664
|
+
True
|
|
665
|
+
|
|
666
|
+
sage: D = distributions.DiscreteGaussianDistributionLatticeSampler(ZZ^3, 3.0, c=(1/2,0,0))
|
|
667
|
+
sage: L = [D() for _ in range(2^12)] # long time
|
|
668
|
+
sage: mean_L = sum(L) / len(L) # long time
|
|
669
|
+
sage: norm(mean_L.n() - D.c()) < 0.25 # long time
|
|
670
|
+
True
|
|
671
|
+
|
|
672
|
+
sage: # needs numpy
|
|
673
|
+
sage: import numpy
|
|
674
|
+
sage: M = matrix(ZZ, [[1,2],[0,1]])
|
|
675
|
+
sage: D = distributions.DiscreteGaussianDistributionLatticeSampler(M, 20.0)
|
|
676
|
+
sage: L = [D() for _ in range(2^12)] # long time
|
|
677
|
+
sage: div = numpy.mean([abs(x) for x,y in L]) / numpy.mean([abs(y) for x,y, in L]) # long time
|
|
678
|
+
sage: 0.9 < div < 1.1 # long time
|
|
679
|
+
True
|
|
680
|
+
|
|
681
|
+
"""
|
|
682
|
+
if not self.is_spherical:
|
|
683
|
+
v = self._call_non_spherical()
|
|
684
|
+
elif self._c_in_lattice_and_lattice_trivial:
|
|
685
|
+
v = self._call_simple()
|
|
686
|
+
else:
|
|
687
|
+
v = self._call()
|
|
688
|
+
v.set_immutable()
|
|
689
|
+
return v
|
|
690
|
+
|
|
691
|
+
def f(self, x):
|
|
692
|
+
r"""
|
|
693
|
+
Compute the Gaussian `\rho_{\Lambda, c, \Sigma}`.
|
|
694
|
+
|
|
695
|
+
EXAMPLES::
|
|
696
|
+
|
|
697
|
+
sage: Sigma = Matrix(ZZ, [[5, -2, 4], [-2, 10, -5], [4, -5, 5]])
|
|
698
|
+
sage: D = distributions.DiscreteGaussianDistributionLatticeSampler(ZZ^3, Sigma)
|
|
699
|
+
sage: D.f([1, 0, 1])
|
|
700
|
+
0.802518797962478
|
|
701
|
+
sage: D.f([1, 0, 3])
|
|
702
|
+
0.00562800641440405
|
|
703
|
+
"""
|
|
704
|
+
try:
|
|
705
|
+
x = vector(ZZ, self.n, x)
|
|
706
|
+
except TypeError:
|
|
707
|
+
try:
|
|
708
|
+
x = vector(QQ, self.n, x)
|
|
709
|
+
except TypeError:
|
|
710
|
+
x = vector(self._RR, self.n, x)
|
|
711
|
+
x -= self._c
|
|
712
|
+
if self.is_spherical:
|
|
713
|
+
return exp(-x.norm() ** 2 / (2 * self._sigma**2))
|
|
714
|
+
return exp(-x * self.sigma_inv * x / 2)
|
|
715
|
+
|
|
716
|
+
def sigma(self):
|
|
717
|
+
r"""
|
|
718
|
+
Gaussian parameter `\sigma`.
|
|
719
|
+
|
|
720
|
+
If `\sigma` is a real number, samples from this sampler will have expected norm
|
|
721
|
+
`\sqrt{n}\sigma` where `n` is the dimension of the lattice.
|
|
722
|
+
|
|
723
|
+
EXAMPLES::
|
|
724
|
+
|
|
725
|
+
sage: D = distributions.DiscreteGaussianDistributionLatticeSampler(ZZ^3, 3.0, c=(1,0,0))
|
|
726
|
+
sage: D.sigma()
|
|
727
|
+
3.00000000000000
|
|
728
|
+
"""
|
|
729
|
+
return self._sigma
|
|
730
|
+
|
|
731
|
+
def c(self):
|
|
732
|
+
r"""
|
|
733
|
+
Center `c`.
|
|
734
|
+
|
|
735
|
+
Samples from this sampler will be centered at `c`.
|
|
736
|
+
|
|
737
|
+
EXAMPLES::
|
|
738
|
+
|
|
739
|
+
sage: D = distributions.DiscreteGaussianDistributionLatticeSampler(ZZ^3, 3.0, c=(1,0,0)); D
|
|
740
|
+
Discrete Gaussian sampler with Gaussian parameter σ = 3.00000000000000, c=(1, 0, 0) over lattice with basis
|
|
741
|
+
<BLANKLINE>
|
|
742
|
+
[1 0 0]
|
|
743
|
+
[0 1 0]
|
|
744
|
+
[0 0 1]
|
|
745
|
+
|
|
746
|
+
sage: D.c()
|
|
747
|
+
(1, 0, 0)
|
|
748
|
+
"""
|
|
749
|
+
return self._c
|
|
750
|
+
|
|
751
|
+
def set_c(self, c):
|
|
752
|
+
r"""
|
|
753
|
+
Modifies center `c`.
|
|
754
|
+
|
|
755
|
+
EXAMPLES::
|
|
756
|
+
|
|
757
|
+
sage: D = distributions.DiscreteGaussianDistributionLatticeSampler(ZZ^3, 3.0, c=(1,0,0))
|
|
758
|
+
sage: D.set_c((2, 0, 0))
|
|
759
|
+
sage: D
|
|
760
|
+
Discrete Gaussian sampler with Gaussian parameter σ = 3.00000000000000, c=(2, 0, 0) over lattice with basis
|
|
761
|
+
<BLANKLINE>
|
|
762
|
+
[1 0 0]
|
|
763
|
+
[0 1 0]
|
|
764
|
+
[0 0 1]
|
|
765
|
+
"""
|
|
766
|
+
if c is None:
|
|
767
|
+
self._c = None
|
|
768
|
+
return
|
|
769
|
+
|
|
770
|
+
if c == 0:
|
|
771
|
+
c = vector(ZZ, self.n)
|
|
772
|
+
else:
|
|
773
|
+
try:
|
|
774
|
+
c = vector(ZZ, self.n, c)
|
|
775
|
+
except TypeError:
|
|
776
|
+
try:
|
|
777
|
+
c = vector(QQ, self.n, c)
|
|
778
|
+
except TypeError:
|
|
779
|
+
try:
|
|
780
|
+
c = vector(self._RR, self.n, c)
|
|
781
|
+
except TypeError:
|
|
782
|
+
c = vector(self._RR, self.n)
|
|
783
|
+
|
|
784
|
+
self._c = c
|
|
785
|
+
self._precompute_data()
|
|
786
|
+
|
|
787
|
+
def __repr__(self):
|
|
788
|
+
r"""
|
|
789
|
+
EXAMPLES::
|
|
790
|
+
|
|
791
|
+
sage: D = distributions.DiscreteGaussianDistributionLatticeSampler(ZZ^3, 3.0, c=(1,0,0)); D
|
|
792
|
+
Discrete Gaussian sampler with Gaussian parameter σ = 3.00000000000000, c=(1, 0, 0) over lattice with basis
|
|
793
|
+
<BLANKLINE>
|
|
794
|
+
[1 0 0]
|
|
795
|
+
[0 1 0]
|
|
796
|
+
[0 0 1]
|
|
797
|
+
|
|
798
|
+
sage: Sigma = Matrix(ZZ, [[10, -6, 1], [-6, 5, -1], [1, -1, 2]])
|
|
799
|
+
sage: D = distributions.DiscreteGaussianDistributionLatticeSampler(ZZ^3, Sigma); D
|
|
800
|
+
Discrete Gaussian sampler with Gaussian parameter Σ =
|
|
801
|
+
[ 10.0000000000000 -6.00000000000000 1.00000000000000]
|
|
802
|
+
[-6.00000000000000 5.00000000000000 -1.00000000000000]
|
|
803
|
+
[ 1.00000000000000 -1.00000000000000 2.00000000000000], c=(0, 0, 0) over lattice with basis
|
|
804
|
+
<BLANKLINE>
|
|
805
|
+
[1 0 0]
|
|
806
|
+
[0 1 0]
|
|
807
|
+
[0 0 1]
|
|
808
|
+
"""
|
|
809
|
+
if self.is_spherical:
|
|
810
|
+
sigma_str = f"σ = {self._sigma}"
|
|
811
|
+
else:
|
|
812
|
+
sigma_str = f"Σ =\n{self._sigma}"
|
|
813
|
+
return f"Discrete Gaussian sampler with Gaussian parameter {sigma_str}, c={self._c} over lattice with basis\n\n{self.B}"
|
|
814
|
+
|
|
815
|
+
def _call_simple(self):
|
|
816
|
+
r"""
|
|
817
|
+
Return a new sample assuming `c \in \Lambda(B)` and `B^* = 1`.
|
|
818
|
+
|
|
819
|
+
EXAMPLES::
|
|
820
|
+
|
|
821
|
+
sage: D = distributions.DiscreteGaussianDistributionLatticeSampler(ZZ^3, 3.0, c=(1,0,0))
|
|
822
|
+
sage: L = [D._call_simple() for _ in range(2^12)]
|
|
823
|
+
sage: mean_L = sum(L) / len(L)
|
|
824
|
+
sage: norm(mean_L.n() - D.c()) < 0.25
|
|
825
|
+
True
|
|
826
|
+
|
|
827
|
+
.. NOTE::
|
|
828
|
+
|
|
829
|
+
Do not call this method directly, call
|
|
830
|
+
:func:`DiscreteGaussianDistributionLatticeSampler.__call__` instead.
|
|
831
|
+
"""
|
|
832
|
+
w = self.VS([d() for d in self.D], check=False)
|
|
833
|
+
return w * self.B + self._c
|
|
834
|
+
|
|
835
|
+
def _call(self):
|
|
836
|
+
"""
|
|
837
|
+
Return a new sample.
|
|
838
|
+
|
|
839
|
+
EXAMPLES::
|
|
840
|
+
|
|
841
|
+
sage: D = distributions.DiscreteGaussianDistributionLatticeSampler(ZZ^3, 3.0, c=(1/2,0,0))
|
|
842
|
+
sage: L = [D._call() for _ in range(2^12)]
|
|
843
|
+
sage: mean_L = sum(L) / len(L)
|
|
844
|
+
sage: norm(mean_L.n() - D.c()) < 0.25
|
|
845
|
+
True
|
|
846
|
+
|
|
847
|
+
.. NOTE::
|
|
848
|
+
|
|
849
|
+
Do not call this method directly, call
|
|
850
|
+
:func:`DiscreteGaussianDistributionLatticeSampler.__call__` instead.
|
|
851
|
+
"""
|
|
852
|
+
v = 0
|
|
853
|
+
c, sigma, B = self._c, self._sigma, self.B
|
|
854
|
+
|
|
855
|
+
m = self.B.nrows()
|
|
856
|
+
|
|
857
|
+
for i in range(m - 1, -1, -1):
|
|
858
|
+
b_ = self._G[i]
|
|
859
|
+
c_ = c.dot_product(b_) / b_.dot_product(b_)
|
|
860
|
+
sigma_ = sigma / b_.norm()
|
|
861
|
+
assert sigma_ > 0
|
|
862
|
+
z = DiscreteGaussianDistributionIntegerSampler(sigma=sigma_, c=c_, algorithm='uniform+online')()
|
|
863
|
+
c = c - z * B[i]
|
|
864
|
+
v = v + z * B[i]
|
|
865
|
+
return v
|
|
866
|
+
|
|
867
|
+
def add_offline_samples(self, cnt=1):
|
|
868
|
+
"""
|
|
869
|
+
Precompute samples from `B^{-1}D_1` to be used in :meth:`_call_non_spherical`.
|
|
870
|
+
|
|
871
|
+
EXAMPLES::
|
|
872
|
+
|
|
873
|
+
sage: Sigma = Matrix([[5, -2, 4], [-2, 10, -5], [4, -5, 5]])
|
|
874
|
+
sage: D = distributions.DiscreteGaussianDistributionLatticeSampler(ZZ^3, Sigma)
|
|
875
|
+
sage: assert not D.is_spherical
|
|
876
|
+
sage: D.add_offline_samples(2^12)
|
|
877
|
+
sage: L = [D() for _ in range(2^12)] # Takes less time
|
|
878
|
+
"""
|
|
879
|
+
# Just to document the difference with [Pei2010]_, in the paper (Algo 1)
|
|
880
|
+
# he samples from Λ + c, but we instead sample from Λ with distribution
|
|
881
|
+
# sampled at c (D_{Λ, c}), but that's the same as c + D_{Λ - c}
|
|
882
|
+
# Also, we use row notation instead of column notation. Sorry.
|
|
883
|
+
for _ in range(cnt):
|
|
884
|
+
coord = [normalvariate(mu=0, sigma=1) for _ in range(self.n)]
|
|
885
|
+
self.offline_samples.append(vector(self._RR, coord) * self.B2_B_inv)
|
|
886
|
+
|
|
887
|
+
def _call_non_spherical(self):
|
|
888
|
+
"""
|
|
889
|
+
Return a new sample.
|
|
890
|
+
|
|
891
|
+
EXAMPLES::
|
|
892
|
+
|
|
893
|
+
sage: Sigma = Matrix([[5, -2, 4], [-2, 10, -5], [4, -5, 5]])
|
|
894
|
+
sage: D = distributions.DiscreteGaussianDistributionLatticeSampler(ZZ^3, Sigma, c=(1/2,0,0))
|
|
895
|
+
sage: L = [D._call_non_spherical() for _ in range(2^12)]
|
|
896
|
+
sage: mean_L = sum(L) / len(L)
|
|
897
|
+
sage: norm(mean_L.n() - D.c()) < 0.25
|
|
898
|
+
True
|
|
899
|
+
|
|
900
|
+
.. NOTE::
|
|
901
|
+
|
|
902
|
+
Do not call this method directly, call
|
|
903
|
+
:func:`DiscreteGaussianDistributionLatticeSampler.__call__` instead.
|
|
904
|
+
"""
|
|
905
|
+
if len(self.offline_samples) == 0:
|
|
906
|
+
self.add_offline_samples()
|
|
907
|
+
vec = self._c_mul_B_inv - self.offline_samples.pop()
|
|
908
|
+
return self._randomise(vec) * self.B
|